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