为什么会执行两次,你能解答出来吗?

Tenadolanter
  • 98

代码如下:

var T = function(){
    this.init.apply(this, arguments)
}
T.prototype.init = function(){
    console.log(111)
}
var t = new T;
t.init()
评论
阅读 666
5 个回答
✓ 已被采纳

执行 new 操作的时候,发生了这些事:
1、创建一个新对象,继承 T.prototype。
2、使用指定的参数调用构造函数 T ,并将 this 绑定到新创建的对象。new T 等同于 new T(),也就是没有指定参数。
3、由构造函数 T 返回的对象就是 new 表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。

构造函数 + 直接调用

function的apply方法是会立刻执行一次这个function的,call同理。如果你只是要指定function的this而不立刻执行它,用bind

coulthard
  • 4
新手上路,请多包涵

第一次执行是初始化时候会调用构造函数,第二次是直接调用

使用apply()改变this的指向,会立即执行。
也就说,new T会直接执行init()函数,返回执行的结果,所以会打印一次111,然后返回undefined
然后你在调用了init()就再执行一次,所以是两次执行。

建议你可以看看:call() 、 apply() 、bind()方法的作用和区别

如上代码可以分两步执行,我们分别看看打印的是什么

第一段代码:

var T = function(){
    this.init.apply(this, arguments)
}
T.prototype.init = function(){
    console.log(111)
}
var t = new T;

第二段代码:

t.init()

可以看到,两段代码都打印出了内容,都是111,那么为什么会这样呢?第二段代码打印111比较容易理解,那么第一段为什么会打印内容呢?

这里涉及到new操作符的内部实现,1.创建一个新对象,2.继承原型,3.将this指向新创建的对象,并执行构造函数(如下P),4.返回新对象

如下为一个简单的new方法实现(不要用在项目里):

function _new(obj){
    var o = {}
    o.__proto__ = obj.prototype;
    obj.apply(o);// 执行了问题里的T方法
    return o;
}

// 测试用例
function P(){
    this.name = 'test'
}
var t = _new(P);
console.log(t.name)

因为new操作会执行构造函数里面的代码,所以会执行T构造函数里面的代码this.init.apply(this, arguments),所以new T也会打印111

宣传栏