js权威指南读书笔记x
第一章 词法结构
Js 是用 Unicode 字符集编写的; js 区分大小写,而 html 不区分;直接量;标志符合保 留字;分号可选,注意良好的编程习惯。
第二章 类型、值和变量
数字
Js不区分整数值和浮点数值,所有值都用浮点数值表示。
整型直接量有十六进制( ox 或 Ox 前缀),八进制( 0 开始,可能不支持) ,还有十进 制。
Infinity :无穷大
-Infinity :负无穷大
NaN != NaN (返回 true)
0 === -0
Js采用一种二进制表示法,不能精确到类似 0.1这样的数字,应避免小数,使用大整
数,如 10 分而非 0.1 元
文本
字符串直接量
转义字符: \
字符串: js 中字符串是固定不变的, 使用方法后都返回新字符串, 字符串本身不改变。
布尔值
任意字符串都可以转换为布尔值,如下列都转换为 false
undefined
null
0
-0
NaN
a ”
布尔值包含 toString() 方法
null 和 undefined
typeof(null) //返回object,可以认为null是一个特殊的对象值,即"非对象” 。
typeof(undefined) //返回 undefine, 表明这个值是这个类型的唯一成员。
两者都不包含任何属性和方法。
全局对象
比如Math和JSON,全局对象的属性是全局定义的符号, js程序可以直接使用。
在代码最顶级, this 可以直接引用全局对象 。
如果代码声明了一个全局变量,这个全局变量就是全局对象的一个属性。
包装对象
Js 对象是属性或已命名值得集合,通过( .)引用属性值,属性值是函数时,称其为方 法。
存取字符串、 数字、 布尔值的属性时创建的临时对象, 它只是偶尔用来区分原始类型和 对象,即它们三者并不是对象,但表现出有属性。
可通过 String (), Number ()或 Boollen ()显式创建包装对象: var s = new String();
== 视原始值和包装对象相等, === 不等。
7?原始值(undefined、null、布尔值、数字和字符串)是不可改变的,修改字符串实际上返 回了一个新的字符串, 原字符串并不改变。
原始值的比较是值的比较, 只有它们的值相等时 才相等。
对象是可变的,值可以修改,但对象的比较并不是值的比较,而是引用的比较,当且 它们引用同一个基对象才相等。
8?类型转换
( 1) == 符号会偏向把两边数据类型转换为数字进行比较。且其从不试图将其操作数转换 为布尔值。
( 2)显式类型转换:
Number() // 等价于 x+ ''
parseInt() // 只解析整数,可接受第二个参数: parseInt(“11”,2) 结果为 3( 1*2+1 )
parseFloat() // 可解析整数和浮点数。
Boolean() // 等价于 +x ,一元运算符
String() // 等价于 !!x ,一元“!”运算符对操作数转换为布尔值并取反。
Object()
方法(都是转换为字符串) :
toString() // 转换为字符串, ()中可以接受转换基数
toFixed() // 根据小数点后的指定位数将数字转换为字符串,不使用指数记数。
toExponential() // 参数指定小数点后面位数,且小数点前只有一位,可使用指数
记数。
toPrecision() // 参数指定有效位数, 有效数字小于数字整数部分数用指数形式。
( 3)对象转换为原始值
toString()
valueOf() // 返回对象本身
9?变量声明
Js 是动态语言类型,声明变量时不用指明类型。
10?变量作用域
在函数体内,局部变量的优先级高于同名的全局变量。声明局部变量时必须使用 var 语
句,不然会生成全局变量。
Js中没有块级作用域,取而代之的是函数作用域:变量在声明它们的函数体以及这个函
数体嵌套的任意函数体内都是有定义的。
即函数内的变量声明 “提前” 至函数体顶部, 同时 变量初始化留在原来的位置。
Js全局变量是全局变量的属性,用 var声明的变量是不可配置的,无法用 delete删除
未声明的变量可配置。
作用域链
第三章 表达式和运算符
原始表达式 如: 1.123 “hello ” /pattern/
对象和数组的初始化表达式
如: var x = [];
var y = {};
函数定义表达式
var squre = function(x){ return x*x;}
属性访问表达式 两种访问方式:
var o = {x:1,y:{z:3}}; o.x; o[“x”]
调用表达式
是一种调用(或者执行)函数或方法的语法表示。
如: f(0)
Math.max(x,y,z)
a.sort()
对象创建表达式
创建一个对象并调用一个函数(构造函数)初始化新对象的属性 如: new object()
new point(2,3)
new object
运算符
左值:表达式只能出现在赋值运算符的左侧。 Js中变量,对象属性和数组元素都是左
值, ECMAScript 规范允许内置函数返回一个左值,但自定义的函数不能返回左值。
( 2)“+”运算符:二元加法运算符,优先考虑为字符串,两侧都不是字符串时理解为数字。
对于不是原始值的操作数会先做类型转换。
对象到原始值的转换规则: 日期对象通过toString()方法执行转换,其他对象则通过 valueOF
()方法执行转换(如果能返回一个原始值) 。但大多数对象都不具备可用的 valueOf ()方
法,则会通过 toString ()方法来转换。
3)一元运算符
+”,“-”:根据需要把操作数转换为数字
++ ”:在操作数之前(前增量) ,对操作数进行增量计算,并返回计算后的值。
在操作数之后(后增量) ,对操作时进行增量计算,但返回未做增量计算的值。
如: var i = 1, j = ++i; // i 和 j 的值都是 2
var I = I, j = i++ // i=2 ,j=1 --”:类似上述。
关系表达式
(1)相等和不等。
“=”:得到或赋值。
“== ”:相等。
// !=
“=== ”:严格相等。
// !== 注意: NaN 和其他任何值都不相等。
(2)比较运算符 操作数只有是数字和字符串才能真正执行比较操作,不是会进行类型转换。
相比“ + ”运算符,字符运算符更偏爱数字,只有两个操作数都是字符串时才会进行字 符串的比较。
(3) in 运算符 希望左操作数是一个字符串或者可以转换为字符串,右操作数是一个对象。如果右侧 的对象拥有一个名为左操作数值的属性名,则返回 true 。
注意: var point = {x:1, y:2}
”toString ”in point //true
toString in point // false
(4) instanceof 运算符 希望左操作数是一个对象,右操作数标识对象的类。如果左侧对象是右侧类的实例, 则返回true,否则false。Js对象的类是通过初始化它们的构造函数来定义的, 则右操作数是
一个函数。
如: var d = new Date();
d instrnceof Date; // true
d instrnceof Object; // true
d instrnceof Number; // false
原型链
逻辑表达式
假值: false null undefined 0 -0 NaN 则其他的值包括对象都是真值。
“&& :左操作数为真值时则返回右操作数的结果。
左操作数为假值时则返回左操作数的的结果,即不计算右操作数的值。
“||”:先计算左操作数的值,结果为真值则返回这个结果。否则返回右操作数结果。
“!”:一元运算符,将操作数的布尔值求反。
赋值表达式
a ”
Data[i++] *=2;
Data[i++] = Data[i++] * 2; // 结果不一样
eval()
解释运行由js源代码组成的字符串,并产生一个值。 eval ()是一个函数,但被当成运
算符对待。
只传入一个参数,如果参数不是字符串则直接返回这个值。是字符串则会当成 js 代码
进行编译,执行后将返回最后一个表达式或语句的值。 eval ()使用了调用它的变量作用域
环境。如:
假如已定义一个局部变量 x
eval(“x”) // 返回局部变量的值
全局 eval()
通过别名调用时,eval ()会将其字符串当成顶级的全局代码来执行,即可能会定义新
的全局变量和全局函数,或给全局函数赋值。 Ie9之前通过execscript ()的全局函数来完成
全局eval ()的功能。
注:严格模式下 eval 不能在局部作用域定义新的变量或函数,可查询或更改。
11.其他运算符
a r ”
“?:”
typeof : 一元运算符,返回值为表示操作数类型的一个字符串。
注:typeof (null)返回object 函数返回function,而不是object。Es3中对所有内置可执
行对象,一律返回 function , es5 中扩充到所有可执行对象,包括内置对象和宿主对象。
Delete: 一元操作符,删除对象属性或者数组元素,删除成功返回 true,否则返回false。
delete希望操作数是一个左值,不是左值则不做任何操作返回 true, —些内置核心和客户端
属性不能删除, var 语句声明的变量不能删除,通过 function 语句定义的函数和函数参数也 不能删除。不能删除数组的长度,只能删除其属性。
Void :一元运算符,操作数会照常计算,但会忽略结算结果并返回 un defi ned。
“,”:二元运算符,先计算左操作数,再计算右操作数。
第四章 语句 表达式计算出一个值,但语句用来执行使某件事发生。
1?语句块:多条语句连接在一起,花括号括起。 Js中没有块级作用域,则语句块中声明的变
量并不是语句块私有的。
空语句:; 如: for(i=0;i<a.length; a[i++]=0);
声明语句: var
function f() {} 函数声明语句可嵌套在其他函数体内,但此时只能出现 在所嵌套函数的顶部。
条件语句
if else if
switch :"相同”是按照“===”运算符进行比较的。return和break都可以用于终止 swich 语句。Es标准允许每个case关键字跟随任意的表达式,用的表较多的是数字和字符串。default 可以放置在 switch 语句内的任何地方。
循环
While do/while for (其中三个表达式任一个都可忽略,但两个分号必不可少。 )
for/in : for(variable in object) strtement
variable 必须是一个适用于赋值表达式左值的值,通常是一个变量名。 Object
是一个表达式,结算结果是一个对象。
如: for(var p in o) console.log(o[p]);
for/in 循环并不会遍历对象的所有属性,只有“可枚举”的属性才会遍历到。
跳转
标签语句:即给语句加上标签,如: mainloop: while(){}
注意: break 和 continue 是 js 中唯一可以使用语句标签的语句。标签的命名 空间和变量或函数的命名空间不同,即它们名字可以相同。
Break:单独使用的作用是立即退出最内层的循环或 switch语句。允许在后面跟随一个标
签语句, 作用是程序将跳转到这个标签所标识的语句块的结束, 或者直接终止这个闭合语句
块的执行。需要注意的是 break的控制权无法越过函数的边界,比如,对一条带标签的函数
定义语句来说,不能从函数内部通过这个标签来跳转到函数外部。
Continue :转到下一次循环,可带有标签。
Return :没有指定返回值都返回 undefined。
throw : throw expression
显式抛出异常。expression可以是任意类型, 通常采用error类型和其子类型,-
个error对象有一个name属性表示错误类型,message属性用于存放传递给构造 函数的字符串。抛出异常时停止当前执行的逻辑,调至就近的异常处理程序
( catch)。
try/carth/finally : try从句定义了需要处理的异常所在的代码块。 catch跟在其后,处理异
常。
Finally 放置清理代码,不管 try 中是否有异常, finally 块中的逻辑 都会执行。
try{}
catch(e){}
finally{}
catch 圆括号内是一个标志符,当捕获到一个异常时,相关值赋值给这 个参数,这个参数具有块级作用域,只在 catch 中定义。
其他语句类型
with :用于临时作用域链
with (object) statement //这条语句将 object 添加到作用域链的头部,然后执行 stateme nt,最后把作用域链恢复到原始状态。
如: with(document.forms[0]){ name.value = “;” address.value = “;” email.value = “;”} // document.forms[0].address.value
注意: with 语句提供了一种读取属性的快捷方式,但不能创建属性。
debugger:当调试程序可用并运行时,js解释器将会以调试模式运行。实际上这条语句 用来产生一个断点。如:
function(o){
if(o ===undefined) debugger; // 用于临时测试
}
use strict”:说明后续的代码将会解析为严格代码。
var hasStrictMode = (function(){ “use strict”;return this===undefined}());
//判断是否支持严格模式。即严格模式下调用的函数中的一个 this 值是
undefined,非严格模式中,总是全局对象。
第五章 对象
对象是一种复合值,可看做是属性的无序集合。
Js 对象还可以从一个称为原型的对象 继承属性。对象的方法通常是属性的继承。
属性特征( property attribute ):可写、可枚举(是否可以通过 for、in 循环返回该属性)
可配置(可以删除或修改该属性) 。
对象特征:对象的原型(prototype)指向另外一个对象,本对象的属性继承自它的原型 对象。
对象的类(class)是一个标识对象类型的字符串。
对象的扩展标记指明了是否可以向该对象添加新属性。
内置对象 宿主对象 自定义对象 自由属性 继承属性
创建对象 ( 1)对象直接量: var point = {x:2,y:3};
( 2)通过 new 创建对象:创建并初始化一个新对象,如: var o = new object();
( 3)原型:每一个对象( null 除外)都从原型继承一个属性。
所有对象直接量都具有同一个原型对象,通过 object,prototype 获得引用。
new Date()创建的对象的原型就是 date.prototype object.prototype
new object() : object.prototype
没有原型的对象不多,如 object.prototype, ,它不继承任何属性 .
object.create(),女口 var o = object.create({x:1,y:2}); // o 继承了属性 x 和 y,使用 第一个参数作为它的原型(可以是 null),第二个参数用于对对象的属性进行进一 步的描述。
例:通过原型继承创建一个新对象 ,即函数返回的新对象继承了参数对象的属性:
function inherit(p){
if (p == null) throw TypeError();
if(Object.create)
return Object.create(p);
var t = typeof p;
if( t !== ”object” && t!== ”function ”) throw TypeError();
function f(){};
f.prototype = p; return new f();
}
属性的查询和设置
如 ;var author = book.author; // 得到 author 属性 book.edition = 6; // 创建一个 edition 属性
( 1) object[ “property ”] // 关联数组, js 对象都是关联数组。
“.“后的是一个标识符, 不可以修改, 而[] 中的属性名可以修改, 因为它们是数据类型。
( 2)继承: js 对象具有“自有属性“,也有一些属性是从原型对象继承而来的。
var unitcircle = {r:1};
var c = inherit(unitcicle);
c,x = 1; c.y = 2; // c 定义了两个属性
c.r = 2; // 覆盖了继承而来的属性 unitcicle.r; // 结果为 1,原型对象没有修改。
( 3)属性访问错误:查询一个不存在的属性不会报错,如果在自身属性和继承的属性 没有找到,返回 undefined 。
给 null 和 defined 设置属性会报错,只读的属性不能重新赋值 ( defineProperty() 中可以对可配置的只读属性重新赋值。 )。
3?删除属性:delete,它只断开属性和宿主对象的联系,而不会去操作属性中的属性。
只能删除自有属性, 不能删除继承属性 (要在定义这个属性的原型上删除, 会 影响到继承这个原型的对象) 。
delete 不能删除那些可配置性为 false 的属性。
delete x // 在严格模式下报错,非严格模式不报错
delete this.x; // 正常
4?检测属性
“in”运算符:如果对象的自由属性或继承属性中包含这个属性返回 true。In可以区分
不存在的属性和存在但值为 undefined 的属性。
var o = { x: undefined }
o.x !== undefined //false 属性存在,但值为 undefined
o.y !== undefined // false 属性不存在
“x” in o // true 属性存在
“y” in o // false 属性不存在
hasOwnPreperty(): 用来检测给定的名字是否是对象的自由属性,返回布尔值。
propertylsEnumerable ():只有检测到时自由属性且这个属性的可枚举性为 true时才返
回 true。
枚举属性 for/in 循环:遍历所有可枚举的属性,包括自有属性和继承属性。
Object.key():是一个函数,返回一个数组,这个数组由对象中可枚举的自有属性 组成(不包括属性的值) 。
Object.getOwnPropertyNames(): 与上述类似,只是它返回对象的所有自由属性的名称,
包括不可枚举的属性。
属性 getter 和 setter
由 getter 和 setter 定义的属性称为“存储器属性” ,不同于数据属性,数据属性只 是一个简单的值。定义存储器属性如下:
var o = {
data_prop: value; // 普通数据属性
get accessor_prop(){ /* 这里是函数体 */}
set accessor_prop(value){ /* 这里是函数体 */ }
} // 这里函数没有用 function 关键字,而是 get 和 set 和数据属性一样。存储性属性是可以继承的
属性的特性 除了名字和值之外,属性还包含一些标识它们可写、可枚举和可配置的特性。在 es3 中无法设置这些特性,所有通过 es3 的程序创建的属性都是可写、可枚举和可配置的,且 无法对这些特性做修改。可认为一个属性包含一个名字和 4个特性:值(value)、可写性
(writable )、可枚举性(enu merable)和可配置型(con figurable )。存储器属性不具有值特性 可写性(由setter方法存在与否决定),它的四个属性是:读取(get)、写入(set)、可枚举 性和可配置性。Es中定义了一个名为"属性描述符” (property descriptor )的对象代表那四
个属性。
Object.getOwnpropertyDescriptor() :获得某个对象的自有的特定属性的属性描述符。要 想获得继承的属性的特性, 需要遍历原型链 ( Object.getPrototypeOf() )
Object.definePeoperty(): 设置属性的特性,要么修改已有属性要么新建自有属性
object.definePeoperty(o, “x”,(writable: false));
设置多个属性: Object.definePeopertys()
对象的三个属性
原型属性:对象的原型属性是用来继承属性的。 Es5中可使用Object.getPrototypeof()
可查询原型。
Es3中使用表达式 o.constructor.prototype来检测一个对象的原型。
var p = {x:1};
var o = Object.create(p); p.isProtrtypeOf(o); // true o 是 p 的原型
Object.prototype.isPrototypeOf(o) // true p 继承自 object.prototype
类属性:是一个字符串,用于表示对象的类型信息。
自定义 classof 函数
( 3)可扩展性:用于表示是否可以给对象添加新属性。
Object.esExtensible(): 判断是否可扩展
Object,preventExtensions() :将对象转换为不可以扩展的,转换后无法设为可扩展。
Object,seal()和Object.preventExtensions()类似,除了能将对象设置为不可扩展的, 还可 以将对象的所有自有属性都设置为不可配置的, 即属性不能删除或配置。
对于 那些已经圭寸闭(sealed)起来的对象是不能解圭寸的。可以使用 Object.isSealed()
来检测对象是否封闭。
Object.freeze ():将对象"冻结”,将对象设为不可扩展,属性设为不可配置,还可以
将它自有的所有数据属性设置为只读的。
Onject.isfrozen() 检测。
序列化对象:是指将对象的状态转化为字符串,也可将字符串还还原为对象。 Es5 中
JSON.stringify()和JSON.parse()用来序列化和还原 js对象。
JSON ( javescript object Notion): javascript 对象表示法。
对象方法
toString ()
toLocaleString ():返回表示这个对象的本地字符串。
toJSON()
ValueOf{}
第六章 数组
数组是值的有序集合
数组创建:如: var b = new Array();
var s = [];
数组元素的读和写
注: a[-1.23] = true; // 即属性名是负整数,这里新建一个名为“ -1.23”的属性
稀疏数组:包含 0 开始的不连续索引的数组。
如: a = new Array(5) // 数组没有元素,但是 a.length = 5。
Firebug 中测试 有值 undefined
a[1000] = 0 ; // 测试结果同上
注:当在数组直接量中省略值时不会创建稀疏数组。如:
var a1 = [,,,]; // 有值 undefined
旧版本中,[1,,3]和[1,undefined,3]结果是一模一样的
数组长度: length 是数组的一个属性。
a = [1,2,3,4,5];
a.length = 3; // 现在 a 为[1,2,3]
数组元素的删除和添加
添加: push
删除:delete删除数组元素后值变为 undefined,变为了稀疏数组,但不修改数组的
length 属性,索引值也不变。
数组遍历
for 循环
for/in
forEach
多维数组: js 不支持真正的多维数组,但可以用数组的嵌套来近似。
es3中的数组方法
join() :将数组中的所有元素都转化为字符串并连接在一起,返回最后生成的字符串,
默认使用逗号分隔。但不该变原数组。如:
var a =[1,2,3];
a.join(); // ”1,2,3”
a.join( “)” // “123”
reverse。:将数组中元素顺序颠倒,返回逆序的数组,原数组改变。
sort():将数组中的元素排序并返回排序后的数组,改变原数组。不带参数时按字母表
顺序排序。传入一个比较函数时,如下:
var a =[1,10,3];
a.sort( function(a,b){ return a-b;}) //根据数值顺序返回, 即a应该在前的话返
回小于 0 的值,在后返回小于 0 的值。
concat():创建并返回一个新数组,不会修改调用的数组。如:
var a = [1,2,3];
a.concat(4,5) // 返回 [1,2,3,4,5]
a,concat([4,5]) // 同上
a.concat(4,[5,[6,7]]) // 返回 [1,2,3,4,5,[6,7]]
slice():指定数组的一个片段或子数组,不会修改调用的数组。
var a = [1,2,3,4,5,6];
a.slice(1,3); //返回 [2,3,4], 根据索引值
splice():在数组中插入或删除元素的通用方法,改变调用的数组。如:
var a = [1,2,3,4,5,6,7,8];
a.splice(4) // 返回 [5,6,7,8] ,a 是[1,2,3,4]
push()和pop():允许将数组当做栈使用,改变数组。 Push()方法在数组的尾部添加一
个或多个元素,并返回长度。Pop
个或多个元素,并返回长度。
Pop 类似,返回删除的值。如:
var stack = [];
var stack = []; stack.push(1,2) stack.pop()
// stack: [1,2] 返回 2
//stack: [1] 返回 2,注意这里是删除的值
unshift()和shift():类似于push ()和pop (),不过他们在数组头部操作。
var a = [2];
a.unshift(1) // a: [1,2] 返回 2,即新数组的长度
a.shift(); // a: [2] 返回 1
a.unshift(3,[4,5]); // a: [3,[4,5],2] 注意是一次性插入 返回 3
9)toString() 和 toLocaleString(): 针对数组将每个元素转化为字符串,用逗号分隔。
如: [1,2,3].toString() // “1,2,3”
es5中数组方法
大多数方法的第一个参数接收一个函数,并且对数组中的每个元素(或一些)调用该函 数。大多数情况下,调用提供的函数使用三个函数:数组元素、元素索引和数组本身。通常 只需要第一个参数,可忽略后面两个。
大多数 es5 数组方法的第一个参数是一个函数,第二个是可选的。如果有第二个参数, 则调用的函数被看做是第二参数的方法。
Es5 方法都不会改变他们调用的原始数组。传递给 这些方法的函数可以改变。
forEach() :从头至尾遍历数组,为每个元素调用指定的函数。如:
var data = [1,2,3,4,5];
data.forEach(function(v, i, a){a[i] = v+1; });
map() :将调用的数组的每个元素传递给指定的函数, 并返回一个新数组不改变调用的
数组,它包含函数的返回值。如: var a = [1,2,3];
b.map(function(x){return x*x;}) // b 是[1,4,9],a 不变
filter ():返回的数组元素是调用的数组的一个子集。传递的函数是用来逻辑判断的: 给函数返回true或false。如:
var data = [1,2,3,4,5];
data.filter(function(x){return x<3}); // [1,2]
every ()和some ():是数组的逻辑判定,它们对数组元素应用指定的函数进行判定, 返回true或false。女口 :
var data = [1,2,3,4,5];
a.every(function(x){ return x<10;}) // true
a.some(inNaN) //false
reduce ()和reduceRight ():使用指定的函数将数组元素进行组合,生成单个值。
如: var a = [1,2,3,4,5]
var sum = a.reduce(function(x,y){ return x+y}, 0); // 数组求和,第二
参数是初始值。
可选。
reduceRight ()工作原理与reduce一样,不同的是它按照数组索引从高到低。
注意:它们两者都能接收一个可选的参数, 它指定了化简函数调用时的 this关键子上的值。
in dexOf ()和last In dexOf ():搜索整个数组中具有给定值的元素,返回找到的第一 元素的索引,没有找到返回 -1.
数组类型: Array.isArray() 可判断是否是数组( es5)
类数组对象: js 数组方法是特意定义为通用的,因为它们不仅应用在真正的属猪而且
在类数组对象上也能工作。
Es5 中,所有数组但方法都是通用的。可间接使用 Function.call 方法调用: var a = {“0”:”a”,”1”:”b”,”2”:”c”,length:3}; // 类数组对象
Array.prototype.join.call(a, ”+”) // “a+b+c”
(12)作为数组的字符串:es5中,字符串的行为类似于只读的数组。
var s = test;
s.charAt(0) // 返回 t
第七章 函数
1 函数定义:名称标识符:在函数声明语句中必须,在函数定义表达式中可选,如果存在, 该名字只存在于函数体中,并指代该函数对象本身,它将成为函数内部的一个局部变量。
函数声明会被提前,函数定义表达式不会,即在定义之前无法调用它。
嵌套函数:可以访问嵌套它们的函数的参数和变量。
注:函数声明不能出现在循环,条件判断或者 try/catch/finally 以及 with 语句中。
2.函数调用
( 1)函数调用: var total = diatance(0,0,1,2)+distance(2,1,3,5);
注: es3 和 es5 非严格模式下,调用上下文是全局对象。在严格模式下调用上下文则是 undefined 。
(2)方法调用:即该函数是一个对象的属性或数组中的一个元素。
调用上下文。
属性访问表达式由两部分组成: 一个对象和属性名称, 对象成为上下文, 用 this 调用。
方法和 this 关键字是面向对象编程的核心。
任何函数只要作为方法调用实际上都会传入一个 隐式的实参 — 这个实参是一个对象,方法调用的母体就是这个对象。
方法链: $(“:header”).map(function(){return this.id}).get().sort();
注:
This 是一个关键字,不是变量,也不是属性名。 Js 语法不允许对它赋值。
( 3)构造函数调用: var o = new Object(); // 无参数可省略() 构造函数调用创建一个新的空对象,它作为调用上下文。
(4)间接调用:call ()和apply ()。两个方法都允许显式指定所需的 this值,即任何函数
可以作为任何对象的方法来调用,哪怕这个函数不是该对象的方法。
2. 函数的实参和形参
可选形参:传入实参比形参个数少时,剩下的形参都设为 undefined 值。传入实参时, 无法省略第一实参并传入第二个实参,要使用占位符 null 或 undefined。
实参对象:arguments,是一个类数组对象。非严格模式下,函数里的 arguments仅仅
是一个标识符,严格模式下是一个保留字。严格模式中的函数无法使用 argume nts作为形参
名或局部变量名,也不能给其赋值。
Callee 和 caller 属性:实参对象定义了这两个属性。严格模式下出错,非严格模式下, callee
属性指代当前正在执行的函数, caller 是非标准的, 它指代当前正在执行的函数的函数。
如: var factorial = function(){
if ( x<= 1) return 1;
return x*arguments.callee(x-1);
}
将对象属性用作实参:即实参写入一个单独的对象之中。
(4)实参类型: js 方法的形参并未声明类型,在形参传入函数之前也为做任何类型检查。
作为值的函数
如: function squre(x) { return x*x; }
var s = squre(3); // 9
自定义函数属性:函数是一个特殊的对象,可自定义属性。
作为命名空间的函数: 不在任何函数内声明的变量是全局变量, 在整个 js 程序中都是可见 的。
(function(){
// 模块代码
}()); // 这是一个匿名的函数表达式,结束定义后并立即调用它。
闭包
Js 采用词法作用域: 函数的执行依赖于变量作用域, 这个作用域实在函数定义时决定的, 而不是函数调用时决定的。
函数对象可以通过作用域链相互关联起来, 函数体内部的变量都 可以保存在函数作用域内,这种特性成为闭包。如:
var scope = “global scope ”;
function checkscope(){
var scope = “local scope ”;
function f() {return scope; }
return f();
}
checkscope() // “local scope”
每个函数调用都包含一个 this 值,如果闭包这个值不确定,可以将 this 转存到体格变量 中。
arguments 并不是一个关键字,问题与 this 类似。
第八章
推荐访问:读书笔记 读书笔记 权威 指南 js权威指南读书笔记x