js实现new 的问题

js实现new 的问题

这里const result = obj.apply(newObj,reset)不知道为什么要有这一步。
我的理解是第一步把建立出来新对象的proto = 构造函数的prototype,那此时构造函数的实例newObj不就应该有构造函数中的所有属性与方法了吗,求解释,感谢各位

    //自己理解的写法

function myNew(obj,...reset) {

let newObj = Object.create(obj.prototype);

return newObj

}

function Person(name) {

this.name = name;

this.say = function () {

console.log('我是person构造函数的say方法'+name)

}

}

let tempObj = myNew(Person);

console.log(tempObj)

tempObj.say() //打印出来is not a function

    //正确写法

function myNew(obj,...reset) {

let newObj = Object.create(obj.prototype);

const result = obj.apply(newObj,reset);

return result === Object ? result : newObj;

}


回答:

这样可能好理解一点, 一步一步来:

1.function Person本身只是1个普通的函数,因为我可以像下面这样直接调用对吧:

var name = '123';

var say = function() {

console.log('hhh');

}

function Person(name) {

this.name = name;

this.say = function () {

console.log('我是person构造函数的say方法'+name)

}

}

Person('名字');

这样一来,这个函数只是改变了全局作用域上的name和say而已。

2.当你执行new Person(name)的时候,却是不一样的效果:

function Person(name) {

this.name = name;

this.say = function () {

console.log('我是person构造函数的say方法'+name)

}

}

// 全局作用域的name和say不会受影响,b会生成一个新的对象。

const b = new Person('名字');

那么这个new操作到底干了什么呢?
1.创建构造函数,任何使用new操作符的函数都会创建1个新的构造函数。
2.创建构造函数的过程中,虽然你直接使用this.name = xxx赋值了,但实际上隐性的创建了一个新的对象new Object()。所以this的属性都是挂载在这个新的对象上的。

知道了new的操作会执行一遍创建对象即new Obejct的操作,然后再执行一遍给这个对象赋值的操作即this.name = xxx。你就能理解,其实new是进行了两个操作,一是创建新对象,二是给这个对象的属性进行赋值。

结论:
1.所以你的Object.crate操作只是完成了第一步,创建了1个新的对象,但是并没有执行给对象添加属性这一步。因为即使你是创建的Object.create(Person.prototype),也只是继承了Person方法而已,但是本身Person就没有被new过啊,也就并没有创建新的对象,而且没有指定这个对象的this是指向谁,没有赋值。所以你继承的只是一个空壳函数的呢。
2.而apply方法会绑定作用域,即this指向。同时执行这个函数,也就是执行this.name = xxx赋值的操作。所以当你执行了apply操作后,才算是给了这个对象一个完整的生命。


回答:

代码里的obj是构造函数,构造函数被new的时候是会执行里面代码的,apply就是执行构造函数,而构造函数的运行结果如果是一个对象(这里的对象不单指object类型的数据,可以理解为非基础数据)的话,则返回这个对象,所以下面正确写法其实也不对


回答:

class 的属性会被加到 prototype 里。

普通函数里对 this.say 的赋值并不影响 prototype ,就是说 prototype 中并没有 say 函数。需要执行这个构造函数的时候,this.say 才被赋值。所以,要在 obj.apply (执行构造函数) 之后,才可以使用 say


回答:

// obj 意义不够准确,改为 cstr,表示 constructor,也就是构造函数

// 注意,它是一个函数

// 另外,参数列表应该叫 rest,或者叫 args。reset 是重置的意思,不是剩余/其它的意思

function myNew(cstr, ...rest) {

// 先从 cstr 的原形创建一个对象,newObj

let newObj = Object.create(cstr.prototype);

// 然后需要把这个 newObj 作为 cstr 中的 this 来调用 cstr

// 所以用 apply,这表示调用 cstr,但里面的 this 是 newObj,

// 后面是 rest 参数数组,作为 cstr 的参数传递进去

// 如果改用 call,就是 cstr.call(newObj, ...rest)

// 做这一步是为了初始化 this 对象(也就是构造函数本身的作用)

const result = cstr.apply(newObj, rest);

return result === Object ? result : newObj;

}

以上是 js实现new 的问题 的全部内容, 来源链接: utcz.com/p/937210.html

回到顶部