this——隐式传递一个对象的引用(简洁和复用)。
this既不指向函数自身,也不指向函数的词法作用域;
this实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。当一个函数被调用时,会创建一个活动记录(执行上下文),这个记录会包含函数在哪里被调用、函数的调用方式、传入的参数信息等,this就是这个记录的一个属性,在函数执行的过程中被调用。
四条标准:
函数的调用位置,决定this的绑定对象(判断的时候从new依次往前判断)
1、默认规则(独立函数调用):严格模式下typeError:this is undefined;非严格模式:绑定到全局。
2、隐式绑定(上下文对象):对象属性引用链中只有上一层或最后一层在调用位置中起作用。
在分析隐式绑定时,必须在一个对象内部包含一个指向函数的属性,并通过这个属性间接引用函数,从而把this间接绑定到这个对象上。
3、显示绑定:用call和apply直接指定this的绑定对象;或者硬绑定(es5提供的内置方法bind,上下文的作用和bind一样)。
4、new绑定(构造函数):
(1)创建(构造)一个全新的对象;
(2)这个新对象被执行prototype连接;
(3)这个新对象会被绑定到函数调用的this;
(4)如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象。
箭头函数=>:根据外层(函数或者全局)作用域来决定this。
prototype机制:指对象中的一个内部链接引用另一个对象。
本质:对象之间的关联关系。
原型链:如果在第一个对象上没有找到需要的属性或者方法引用,引擎就会继续在prototype关联的对象上进行查找。若后者中也没找到,就会继续查找他的prototype,以此类推。这一系列对象的链接被称为原型链。
例子:
function Fn() {}// Fn为构造函数
var f1 = new Fn();//f1是Fn构造函数创建出来的对象
构造函数的prototype属性值就是对象原型。(Fn.prototype就是对象的原型)
构造函数的prototype属性值的类型就是对象 typeof Fn.prototype===object.
对象原型中的constructor属性指向构造函数 (Fn.prototype.constructor===Fn)
对象的__proto__属性值就是对象的原型。(f1.__proto__就是对象原型)
Fn.prototype===f1.__proto__ 其实它们两个就是同一个对象---对象的原型。
所有Fn.prototype.__proto__===Object.prototype
typeof Object.prototype ===object。
Object.prototype.__proto__===null。
我讨论原型就是指的对象与原型对象之间的关系。所以原型链也称之为对象链。
所以对象f1的原型链:f1.__proto__---->Fn.prototype.__proto__----->Object.prototype.__prototype__---->null
只有函数有prototype,对象是没有的。
但是函数也是有__proto__的,因为函数也是对象。函数的__proto__指向的是Function.prototype。
也就是说普通函数是Function这个构造函数的一个实例。
instanceof原理
instanceof是判断实例对象的__proto__和生成该实例的构造函数的prototype是不是引用的同一个地址。
是返回true,否返回false。
原型链和作用域链的区别:
1、作用域链(针对函数作用域): 全局作用域==》函数1的作用域==》函数1包含的函数2的作用域
2、原型链(针对构造函数):object==》构造函数1==》构造函数2