Skip to content

Commit

Permalink
edit stdlib/json
Browse files Browse the repository at this point in the history
  • Loading branch information
ruanyf committed May 28, 2015
1 parent fc728e8 commit fd09c14
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 122 deletions.
110 changes: 52 additions & 58 deletions dom/css.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ document.styleSheets[0].cssRules[0].style.cssText

- window.getComputedStyle()的返回结果

每一条CSS属性,都是CSSStyleDeclaration对象的属性。
每一条CSS属性,都是CSSStyleDeclaration对象的属性。不过,连词号需要编程骆驼拼写法。

```javascript
var styleObj = document.styleSheets[0].cssRules[1].style;
Expand Down Expand Up @@ -504,107 +504,102 @@ for (var i = styleObj.length - 1; i >= 0; i--) {
styleObj.cssText = '';
```

## window.getComputedStyle方法
## window.getComputedStyle()

getComputedStyle方法接受一个HTML元素作为参数,返回一个包含该HTML元素的最终样式信息的对象。所谓“最终样式信息”,指的是各种CSS规则叠加后的结果。

{% highlight javascript %}
getComputedStyle方法接受一个DOM节点对象作为参数,返回一个包含该节点最终样式信息的对象。所谓“最终样式信息”,指的是各种CSS规则叠加后的结果。

```javascript
var div = document.querySelector('div');

window.getComputedStyle(div).backgroundColor
```

{% endhighlight %}
getComputedStyle方法还可以接受第二个参数,表示指定节点的伪元素。

getComputedStyle方法只能读取CSS属性,而不能设置。它使用骆驼拼写法表示CSS规则名,比如background-color要写成backgroundColor。
```javascript
var result = window.getComputedStyle(div, ':before');
```

getComputedStyle方法返回的颜色值一律都是rgb(#,#,#)格式
getComputedStyle方法返回的是一个CSSStyleDeclaration对象。但是此时,这个对象是只读的,也就是只能用来读取样式信息,不能用来设置。如果想设置样式,应该使用Element节点的style属性

## window.matchMedia方法
```javascript
var elem = document.getElementById("elem-container");
var hValue = window.getComputedStyle(elem,null).getPropertyValue("height");
```

window.matchMedia方法用来检查CSS的[mediaQuery](https://developer.mozilla.org/en-US/docs/DOM/Using_media_queries_from_code)语句。各种浏览器的最新版本(包括IE 10+)都支持该方法,对于不支持该方法的老式浏览器,可以使用第三方函数库[matchMedia.js](https://github.com/paulirish/matchMedia.js/)
## window.matchMedia()

### mediaQuery语句
### 基本用法

mediaQuery有点像if语句,只要显示网页的媒介(包括浏览器和屏幕等)满足mediaQuery语句设定的条件,就会执行区块内部的语句。下面是mediaQuery语句的一个例子
window.matchMedia方法用来检查CSS的[mediaQuery](https://developer.mozilla.org/en-US/docs/DOM/Using_media_queries_from_code)语句。各种浏览器的最新版本(包括IE 10+)都支持该方法,对于不支持该方法的老式浏览器,可以使用第三方函数库[matchMedia.js](https://github.com/paulirish/matchMedia.js/)

{% highlight javascript %}
CSS的mediaQuery语句有点像if语句,只要显示媒介(包括浏览器和屏幕等)满足mediaQuery语句设定的条件,就会执行区块内部的语句。下面是mediaQuery语句的一个例子。

```css
@media all and (max-width: 700px) {
body {
background: #FF0;
}
body {
background: #FF0;
}
}
```

{% endhighlight %}

上面的CSS代码表示,该区块对所有媒介(media)有效,且视口必须满足最大宽度不超过700像素。如果条件满足,则body元素的背景设为#FF0。
上面的CSS代码表示,该区块对所有媒介(media)有效,且视口的最大宽度不得超过700像素。如果条件满足,则body元素的背景设为#FF0。

需要注意的是,mediaQuery接受两种宽度/高度的度量,一种是上例的“视口”的宽度/高度,还有一种是“设备”的宽度/高度,下面就是一个例子。

{% highlight javascript %}

```css
@media all and (max-device-width: 700px) {

body {
background: #FF0;
}
}
```

{% endhighlight %}

视口的宽度/高度(width/height)使用documentElement.clientWidth/Height来衡量,单位是CSS像素;设备的宽度/高度(device-width/device-height)使用screen.width/height来衡量,单位是设备硬件的像素。

### 属性
视口的宽度/高度(width/height)使用documentElement.clientWidth/clientHeight来衡量,单位是CSS像素;设备的宽度/高度(device-width/device-height)使用screen.width/height来衡量,单位是设备硬件的像素。

window.matchMedia方法接受mediaQuery语句作为参数,返回一个[MediaQueryList](https://developer.mozilla.org/en-US/docs/DOM/MediaQueryList)对象。该对象有以下两个属性。
window.matchMedia方法接受一个mediaQuery语句的字符串作为参数,返回一个[MediaQueryList](https://developer.mozilla.org/en-US/docs/DOM/MediaQueryList)对象。该对象有以下两个属性。

- media:查询语句的内容。
- matches:如果查询结果为真,值为true,否则为false。
- media:返回所查询的mediaQuery语句字符串。

{% highlight javascript %}
- matches:返回一个布尔值,表示当前环境是否匹配查询语句。

```javascript
var result = window.matchMedia("(min-width: 600px)");

result.media // (min-width: 600px)
result.matches // true
```

{% endhighlight %}

下面是另外一个例子,根据mediaQuery是否匹配,运行不同的JavaScript代码。

{% highlight javascript %}
下面是另外一个例子,根据mediaQuery是否匹配当前环境,执行不同的JavaScript代码。

```javascript
var result = window.matchMedia('@media all and (max-width: 700px)');

if(result.matches) {
console.log('the width is less then 700px');
if (result.matches) {
console.log('页面宽度小于等于700px');
} else {
console.log('the width is more then 700px');
console.log('页面宽度大于700px');
}
```

{% endhighlight %}

还可以根据mediaQuery是否匹配,加载相应的CSS样式表。

{% highlight javascript %}
下面的例子根据mediaQuery是否匹配当前环境,加载相应的CSS样式表。

```javascript
var result = window.matchMedia("(max-width: 700px)");

if (result.matches){
var linkElm = document.createElement('link');
linkElm.setAttribute('rel', 'stylesheet');
linkElm.setAttribute('type', 'text/css');
linkElm.setAttribute('href', 'small.css');
var linkElm = document.createElement('link');
linkElm.setAttribute('rel', 'stylesheet');
linkElm.setAttribute('type', 'text/css');
linkElm.setAttribute('href', 'small.css');

document.head.appendChild(linkElm);
document.head.appendChild(linkElm);
}
```

{% endhighlight %}

### 方法
### 监听事件

window.matchMedia方法返回的MediaQueryList对象有两个方法,用来监听事件:addListener方法和removeListener方法。如果mediaQuery查询结果发生变化,就调用指定的回调函数。

{% highlight javascript %}

```javascript
var mql = window.matchMedia("(max-width: 700px)");

// 指定回调函数
Expand All @@ -620,8 +615,7 @@ function mqCallback(mql) {
// 宽度大于700像素
}
}

{% endhighlight %}
```

上面代码中,回调函数的参数是MediaQueryList对象。回调函数的调用可能存在两种情况。一种是显示宽度从700像素以上变为以下,另一种是从700像素以下变为以上,所以在回调函数内部要判断一下当前的屏幕宽度。

Expand Down
51 changes: 19 additions & 32 deletions grammar/object.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,19 +289,16 @@ y // 1

### in运算符

in运算符用于检查对象是否包含某个属性(注意,检查的是键名,不是键值),如果包含就返回true。

{% highlight javascript %}
in运算符用于检查对象是否包含某个属性(注意,检查的是键名,不是键值),如果包含就返回true,否则返回false。

```javascript
var o = { p: 1 };
'p' in o // true

{% endhighlight %}
```

该运算符对数组也适用。

{% highlight javascript %}

```javascript
var a = ["hello", "world"];

0 in a // true
Expand All @@ -311,47 +308,37 @@ var a = ["hello", "world"];
'0' in a // true
'1' in a // true
'2' in a // false
```

{% endhighlight %}

上面代码表示,数字键0和1都在数组之中。由于对象的键名都是字符串,因此也可以用字符串1和2判断数组的成员。

在JavaScript语言中,所有全局变量都是顶层对象(浏览器环境的顶层对象为window)的属性,因此可以用in运算符判断一个全局变量是否存在。
上面代码表示,数字键0和1都在数组之中。由于数组是一种特殊对象,而对象的键名都是字符串,所以字符串的”0“和”1“,也是数组的键名。

{% highlight javascript %}
在JavaScript语言中,所有全局变量都是顶层对象(浏览器的顶层对象就是window对象)的属性,因此可以用in运算符判断,一个全局变量是否存在。

```javascript
// 假设变量x未定义

// 报错
// 写法一:报错
if (x){ return 1; }

// 不正确的写法
// 写法二:不正确
if (window.x){ return 1; }

// 正确的写法
// 写法三:正确
if ('x' in window) { return 1; }
```

{% endhighlight %}

上面三种写法之中,如果x不存在,第一种写法会报错;如果x的值对应布尔值false(比如x等于空字符串),第二种写法无法得到正确结果;只有第三种写法,才是判断变量x是否存在的正确写法。

in运算符对继承的属性也有效。
上面三种写法之中,如果x不存在,第一种写法会报错;如果x的值对应布尔值false(比如x等于空字符串),第二种写法无法得到正确结果;只有第三种写法,才能正确判断变量x是否存在。

{% highlight javascript %}
in运算符的一个问题是,它不能识别对象继承的属性。

```javascript
var o = new Object();
o.hasOwnProperty('toString') // false

o.hasOwnProperty('toString')
// false

'toString' in o
// true

{% endhighlight %}

上面代码中,toString方法是对象o的继承属性,hasOwnProperty方法可以说明这一点,而in运算符对继承的属性也返回true。
'toString' in o // true
```

in运算符只能用来检验可枚举(enumerable)的属性。关于可枚举性,参见下一章的《Object对象》一节
上面代码中,toString方法不是对象o自身的属性,而是继承的属性,hasOwnProperty方法可以说明这一点。但是,in运算符不能识别,对继承的属性也返回true

### for...in循环

Expand Down
58 changes: 32 additions & 26 deletions oop/basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -501,10 +501,9 @@ this的动态切换,固然为JavaScript创造了巨大的灵活性,但也使

### call方法

函数的call方法,可以改变指定该函数内部this的指向,然后再调用该函数
函数的call方法,可以指定该函数内部this的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数

```javascript

var o = {};

var f = function (){
Expand All @@ -513,15 +512,13 @@ var f = function (){

f() === this // true
f.call(o) === o // true

```

上面代码中,在全局环境运行函数f时,this指向全局环境;call方法指定,在对象o的环境中运行函数f,则this指向对象o
上面代码中,在全局环境运行函数f时,this指向全局环境;call方法可以改变this的指向,指定this指向对象o,然后在对象o的作用域中运行函数f

再看一个例子。

{% highlight javascript %}

```javascript
var n = 123;
var o = { n : 456 };

Expand All @@ -534,55 +531,64 @@ a.call(null) // 123
a.call(undefined) // 123
a.call(window) // 123
a.call(o) // 456
```

{% endhighlight %}

上面代码中,a函数中的this关键字,如果指向全局对象,返回结果为123。如果使用call方法,将this关键字指向o对象,返回结果为456。如果this所要指向的那个对象,设定为null或undefined,则等同于指向全局对象。
上面代码中,a函数中的this关键字,如果指向全局对象,返回结果为123。如果使用call方法将this关键字指向o对象,返回结果为456。可以看到,如果call方法没有参数,或者参数为null或undefined,则等同于指向全局对象。

call方法的完整使用格式如下。

```javascript

func.call(thisValue, arg1, arg2, ...)

```

它的第一个参数就是this所要指向的那个对象,后面的参数则是函数调用时所需的参数。

```javascript

function add(a,b) {
return a+b;
}

add.call(this,1,2) // 3

```

上面代码中,call方法指定函数add在当前环境(对象)中运行,并且参数为1和2,因此函数add运行后得到3。

### apply方法
call方法的一个应用是调用对象的原生方法。

apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。它的使用格式如下。
```javascript
var obj = {};
obj.hasOwnProperty('toString') // false

{% highlight javascript %}
obj.hasOwnProperty = function (){
return true;
};
obj.hasOwnProperty('toString') // true

func.apply(thisValue, [arg1, arg2, ...])
Object.prototype.hasOwnProperty.call(obj, 'toString') // false
```

{% endhighlight %}
上面代码中,hasOwnProperty是obj对象继承的方法,如果这个方法一旦被覆盖,就不会得到正确结果。call方法可以解决这个方法,它将hasOwnProperty方法的原始定义放到obj对象上执行,这样无论obj上有没有同名方法,都不会影响结果。

### apply方法

apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数,使用格式如下。

```javascript
func.apply(thisValue, [arg1, arg2, ...])
```

apply方法的第一个参数也是this所要指向的那个对象,如果设为null或undefined,则等同于指定全局对象。第二个参数则是一个数组,该数组的所有成员依次作为参数,传入原函数。原函数的参数,在call方法中必须一个个添加,但是在apply方法中,必须以数组形式添加。

请看下面的例子。

{% highlight javascript %}

function f(x,y){ console.log(x+y); }
```javascript
function f(x,y){
console.log(x+y);
}

f.call(null,1,1) // 2
f.apply(null,[1,1]) // 2

{% endhighlight %}
```

上面的f函数本来接受两个参数,使用apply方法以后,就变成可以接受一个数组作为参数。

Expand Down Expand Up @@ -619,7 +625,7 @@ Array.apply(null, ["a",,"b"])
var a = ["a",,"b"];

function print(i) {
console.log(i);
console.log(i);
}

a.forEach(print)
Expand Down Expand Up @@ -668,8 +674,8 @@ o.f = function (){
}

var f = function (){
o.f.apply(o);
// 或者 o.f.call(o);
o.f.apply(o);
// 或者 o.f.call(o);
};

$("#button").on("click", f);
Expand Down
Loading

0 comments on commit fd09c14

Please sign in to comment.