今天看了一本书,一本专业书,丝毫不然人觉得烦躁乏味的专业书。《node.js开发指南》是我看的第一本node.js的书。作为入门来说,至少不会想让人立马从入门到放弃。很喜欢这本书的附录里总结的关于js高级特性的东西,这也是前端校招中必考问题,故而也想顺着这个思路整理一下。膜拜大神BYVoid
作用域
JavaScript 的作用域完全是由函数来决定的,if、for 语句中的花括号不是独立的作用域。
在函数中引用一个变量时,JavaScript 会先搜索当前函数作用域,或者称为“局部作用域”,如果没有找到则搜索其上层作用域,一直到全局作用域。
有一点需要注意:函数作用域的嵌套关系是定义时决定的,而不是调用时决定的,也就是说,JavaScript 的作用域是静态作用域,又叫词法作用域,这是因为作用域的嵌套关系可以在语法分析时确定,而不必等到运行时确定。
满足以下条件的变量属于全局作用域:
在最外层定义的变量;
全局对象的属性;
任何地方隐式定义的变量(未定义直接赋值的变量)。
node.js最后那个没有最外层定义的变量,它是以模块的形式存在,模块不是最外层的。所以在node.js中,没有最外层定义的变量。全局对象是global对象。
闭包
由函数(环境)及其封闭的自由变量组成的集合体。
(这个概念太难懂了…)
当一个函数返回它内部定义的一个函数时,就产生了一个闭包,
闭包不但包括被返回的函数,还包括这个函数的定义环境。
闭包的用途
- 嵌套的回调函数
- 实现私有成员
JavaScript的对象没有私有属性,也就是说对象的每一个属性都是曝露给外部的。闭包可以让函数内部变量对外不可见。只能通过返回的函数来使用。
对象
- 使用关联数组访问对象成员
- 使用对象初始化器创建对象
使用初始化器时,对象属性名称是否加引号是可选的,除非属性名称中有空格或者其他可能造成歧义的字符,否则没有必要使用引号。
1 | var foo = { |
- 构造函数
1 | function User(name, uri) { |
- 上下文对象
this 指针不属于某个函数,而是函数调用时所属的对象。使用不同的引用来调用同一个函数时,this 指针永远是这个引
用所属的对象。
在 JavaScript 中,本质上,函数类型的变量是指向这个函数实体的一个引用,在引用之间赋值不会对对象产生复制行为。我们可以通过函数的任何一个引用调用这个函数,不同之处仅仅在于上下文。 - call && apply && bind
call 和 apply 的功能是以不同的对象作为上下文来调用某个函数。简而言之,就是允许一个对象去调用另一个对象的成员函数。
call 和 apply 的功能是一致的,两者细微的差别在于 call 以参数表来接受被调用函数的参数,而apply以数组来接受被调用函数的参数。call 和 apply 的语法分别是:func.call(thisArg[, arg1[, arg2[, ...]]])
func.apply(thisArg[, argsArray])
通过这种方法,将func的上下文对象变成了thisArg
bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
即使用bind方法来永久地绑定函数的上下文,使其无论被谁调用,上下文都是固定的。bind 语法如下:
func.bind(thisArg[, arg1[, arg2[, …]]])
bind方法还有一个重要的功能:绑定参数表。
一篇别人的总结,附有比较详细的例子
- 原型
通过原型和构造函数初始化对象的区别
- 构造函数内定义的属性继承方式与原型不同,子对象需要显式调用父对象才能继承构造函数内定义的属性。
- 构造函数内定义的任何属性,包括函数在内都会被重复创建,同一个构造函数产生的两个对象不共享实例。
- 构造函数内定义的函数有运行时闭包的开销,因为构造函数内的局部变量对其中定义的函数来说也是可见的。
两种方式分别使用的情况
除非必须用构造函数闭包,否则尽量用原型定义成员函数,因为这样可以减少开销。
尽量在构造函数内定义一般成员,尤其是对象或数组,因为用原型定义的成员是多个实例共享的。
原型链
JavaScript 中有两个特殊的对象: Object 与 Function,它们都是构造函数,用于生成对象。Object.prototype
是所有对象的祖先,Function.prototype
是所有函数的原型,包括构造函数。
把JS对象大致分为三类:
- 用户创建的对象:new 显式创建的对象
- 构造函数对象:new调用普通对象生成的函数对象
- 原型对象:特指构造函数 prototype 属性指向的对象
- 所有的对象都有__proto__属性,该属性对应该对象的原型.
- 所有的函数对象都有prototype属性,该属性的值会被赋值给该函数创建的对象的_proto_属性.
- 所有的原型对象都有constructor属性,该属性对应创建所有指向该原型的实例的构造函数.
- 函数对象和原型对象通过prototype和constructor属性进行相互关联.
对象克隆
- 浅克隆
- 深克隆