如下是我的对这三个老大难的总结(最近一直在学习原生JS,翻了很多书,很多文档,虽然仍是新手,但我会继续坚持走我本身的路)闭包
全部对象都是基于Object.prototype
,Object.prototype
就是JavaScript的根对象,在Object.prototype
中定义的方法均可以被其它对象访问到,固然也能够被重写了,因此直接在Object.prototype
上调用的是原始功能的toString()
方法,该方法会放回参数对象的内置属性[[class]]
的值,这个值是个字符串,好比'[Object String]'
app
要理解原型链机制的话,首先得知道根本缘由:JavaScript中的对象都有一个内置属性[[Prototype]]
,这个属性和非标准的__proto__
属性同样,__proto__
在ES6中被归入标准了,能够说它们基本上是等价的,但内置属性是没法访问到的。对象之间经过内置属性[[Prototype]]
关联了起来就造成了原型链,而原型链的顶层就是根对象Object.prototype
,Object.prototype
的原型将是null
,即Object.prototype.__proto__ === null;
函数
例如:
在访问对象的属性的时候,如:obj.a
,首先查找自身,没有,就到它的内置属性[[Prototype]]
所引用的对象上找,仍是没有,就继续在这个上层对象的内置属性[[Prototype]]
所引用的对象上找,一直找到根对象Object.prototype
,找不到就返回undefined
;学习
理解this的第一步就是要明白:this
既不指向函数自身,也不指向函数的词法做用域;
this是在运行时进行绑定的,而不是在编写时绑定,它的上下文取决于函数调用时的各类条件;
this的绑定和函数声明的位置没有任何关系,只取决于函数的调用位置和调用方式;
this绑定规则有4点:按优先级1到4判断this
由new调用?绑定到新建立的空对象;prototype
由call、apply、bind
调用?绑定到指定的参数对象;如foo.call(obj)
code
由上下文对象调用?绑定到这个上下文对象;如obj.foo()
对象
默认状况下绑定到全局对象,foo()
;在严格模式下绑定到undefined
;ip
function foo(){ var a = 2; function bar(){} return bar; } var a = foo(); a();
闭包:不是指函数bar也不是a,它是一个引用,这个引用被内部函数bar持有,这个引用指向外部函数foo的整个做用域,它使得这个做用域即便在外部函数foo()执行后也不会被垃圾回收器回收。也就是说这个外部函数foo的做用域就是闭包自己。
不管经过何种手段(直接或间接)将内部函数传递到所在的词法做用域之外,它都会持有对原始定义做用域的引用,不管在何处执行这个函数都会使用闭包。原型链
var fn; //间接传递函数 function foo(){ var a = 2; function baz(){ console.log(a); } fn = baz; } function bar(){ fn();} foo(); bar();
function foo(){ var a = 2; function baz(){ console.log(a); } bar(baz); } function bar(fn){ fn(); }