MDN中对new的解释:
developer.mozilla.org./zh-CN/docs/…
new做了什么?
-
创建一个空的简单JavaScript对象(即
{}); -
为步骤1新创建的对象添加属性
__proto__,将该属性链接至构造函数的原型对象 ;至此我们要理解下面的代码
obj.__proto__ = fn.prototype,这里就需要联想到原型的三角关系。
-
原型:每个函数都会自动附带一个属性
prototype,这个属性的值是一个普通对象,称之为原型对象 -
instance,通过
new产生的对象称之为实例。(由于JS中所有对象都是通过
new产生的,因此,严格来说,JS中所有对象都称之为实例) -
每个实例都拥有一个特殊的属性
__proto__,称之为隐式原型,它指向构造函数的原型 。 -
将步骤1新创建的对象作为
this的上下文 ; -
如果该函数没有返回对象,则返回
this
有些同学可能不理解什么是上下文,请看下面。
this(上下文对象)
执行上下文:global、function 或 eval。分为全局上下文,函数上下文,类上下文。
this(上下文对象):this指向的是一个对象,这个对象我们称为函数执行的上下文对象 。
-
我们每次调用函数时,解析器都会将this作为隐含的参数传递进函数。
-
使用this,根据函数的调用形式不同,this的值也不同(this会指向不同的对象)。
-
this 关键字是 JS 中的动态作用域机制,是为了在 JS 中加入动态作用域而做的努力,因为this指向的对象是在函数调用时绑定的。
在任何函数中,this的指向都不是静态的(static)。它总是在你调用一个函数,但尚未执行函数内部代码前被指定。即this的指向与函数被调用的方式(语法)有关。
-
this在不同情况下的指向
- 以函数的形式调用时,this是window
- 以方法的形式调用时,this是调用方法的对象(如果以类的静态方法调用时,即
Demo.test(),这里Demo是一个类,this此时指向这个类) - 以构造函数的形式调用时,this就是新创建的对象
- 以
call()和apply()的方法调用时,this就是指定的那个对象。
如何手写new?
function myNew(fn, ...args) {
let obj = {};
obj.__proto__ = fn.prototype;
const result = fn.apply(obj, args);
return result instanceof Object && result!=null? result : obj;
}
function Test(name) {
this.name = name;
this.print = function(){
console.log('name:'+this.name)
}
}
const test = myNew(Test, "demo");
console.log(test,test.name);
test.print()