New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[js] 第22天 你对new操作符的理解是什么?手动实现一个new方法 #76
Comments
new 的理解
new步骤模拟new操作前,要先知道new操作是发生了什么,就拿
构造函数:先准备一个构造函数来
原生new:
模拟new模拟的
得到和new 一样的答案,说明模拟成功。 |
function _new(Fn, ...arg) { 之前在github看另外一个人写的 |
|
function myNew(fn){
var obj = {};
Object.setPrototypeOf(obj,fn.prototype)
obj.apply(fn)
return obj
} |
|
function customNew(fn) {
const obj = {};
return function (...args) {
const res = fn.apply(obj, args);
obj.__proto__ = Object.getPrototypeOf(fn);
return typeof res === "object" ? res : obj
}
}
function Foo(name) {
this.name = name
}
console.log(customNew(Foo)(2)); |
/**
* 模拟实现 new 操作符
* @param {Function} ctor [构造函数]
* @return {Object|Function|Regex|Date|Error} [返回结果]
*/
function newOperator(ctor){
if(typeof ctor !== 'function'){
throw 'newOperator function the first param must be a function';
}
// ES6 new.target 是指向构造函数
newOperator.target = ctor;
// 1.创建一个全新的对象,
// 2.并且执行[[Prototype]]链接
// 4.通过`new`创建的每个对象将最终被`[[Prototype]]`链接到这个函数的`prototype`对象上。
var newObj = Object.create(ctor.prototype);
// ES5 arguments转成数组 当然也可以用ES6 [...arguments], Aarry.from(arguments);
// 除去ctor构造函数的其余参数
var argsArr = [].slice.call(arguments, 1);
// 3.生成的新对象会绑定到函数调用的`this`。
// 获取到ctor函数返回结果
var ctorReturnResult = ctor.apply(newObj, argsArr);
// 小结4 中这些类型中合并起来只有Object和Function两种类型 typeof null 也是'object'所以要不等于null,排除null
var isObject = typeof ctorReturnResult === 'object' && ctorReturnResult !== null;
var isFunction = typeof ctorReturnResult === 'function';
if(isObject || isFunction){
return ctorReturnResult;
}
// 5.如果函数没有返回对象类型`Object`(包含`Functoin`, `Array`, `Date`, `RegExg`, `Error`),那么`new`表达式中的函数调用会自动返回这个新的对象。
return newObj;
} 参考 https://juejin.im/post/5bde7c926fb9a049f66b8b52#heading-5 |
|
new 操作会执行以下几步:
function newFn(C, ...args) {
const o = Object.create(C.prototype);
const o2 = C.apply(o, args);
return o2 instanceof Object ? o2 : o;
} |
|
对一个实例new做了以下4件事
实现方法,楼上大佬的
|
推荐看 mdn new运算符 |
// new 的实现原理
// 创建一个新对象
// 将新对象的_proto_指向构造函数的prototype对象
// 将构造函数的作用域赋值给新对象 (也就是this指向新对象)
// 执行构造函数中的代码(为这个新对象添加属性)
// 返回新的对象
function _new(fn,...arg){
//将创建的对象的原型指向构造函数的原型 ==> 新对象.__proto__(原型) == fn.prototype
const obj = Object.create(fn.prototype);
// 将this指向新对象
const ret = fn.apply(obj,arg);
//判断返回值 (如果构造函数本身有返回值且是对象类型,就返回本身的返回值,如果没有才返回新对象)
return ret instanceof Object ? ret : obj;
} |
+1 |
new操作符做了四件事:初始化一个对象、将对象的原型指向构造函数的prototype、将构造函数的this指向这个对象、返回这个对象。 function objectFactory() {
let object = new Object(), Constractor = [].shift.call(arguments);
object.__proto__ = Constractor.prototype;
Constractor.apply(object, arguments)
return object;
} |
const myNew = (Ctor, ...args) => {
let instance = {}
Object.setPrototypeOf(instance, Ctor.prototype)
const res = Ctor.apply(instance, args)
// 如果构造方法已经return了一个对象,那么就返回该对象, 否则返回myNew创建的新对象 obj
if (typeof res === "function" || (typeof res === "object" && res !== null)) {
return res
}
return instance
}
function F(name) {
this.name = name
}
const f = myNew(F, '7 yue')
console.log(f)
console.log(f instanceof F) |
Reflect.construct(target, argumentsList[, newTarget]) // 新的思路 |
function create(fun, ...args) {
const obj = Object.create(fun.prototype);
obj.constructor = fun;
const res = fun.call(obj, ...args);
return isPrimitive(res) ? obj : res;
}
const isPrimitive = (val) => Object(val) !== val;
function Apple(name, count){
this.name = name
this.count = count
}
var a = create(Apple, 'apple', 3)
console.log(a)
// Apple { constructor: [Function: Apple], name: 'apple', count: 3 } |
|
我的理解是这样的: obj 和 obj1 原则上应该是同一个对象的引用。 |
实例化一个对象。 |
实例化对象 |
实现function _new(constructor, ...arg) {
// 1.创建一个空对象
let obj = {};
// 2.为步骤1新创建的对象添加属性__proto__,将该属性链接至构造函数的原型对象prototype
obj.__proto__ = constructor.prototype;
// 3.将步骤1新创建的对象作为this的上下文
let res = constructor.apply(obj, arg);
// 4.如果该函数没有返回对象,则返回this
// return typeof res === "object" ? res : obj;
return Object.prototype.toString.call(res) === "[object Object]"
? res
: obj;
}
const Fun = function (name) {
this.name = name;
};
console.log(_new(Fun, "Tom")); |
|
创建一个新对象 function objectFactory(){ |
可以加入一些内存方面的理解 |
new的背后操作:
|
// 1 创建一个空对象
|
|
1、对new操作符的理解
|
在JavaScript中,
下面是一个手动实现 function myNew(constructor, ...args) {
// 创建一个新的空对象,并将其原型指向构造函数的原型
const obj = Object.create(constructor.prototype);
// 将构造函数的作用域赋给新对象
const result = constructor.apply(obj, args);
// 如果构造函数有显式地返回一个对象,则返回该对象;否则返回新对象
return (typeof result === 'object' && result !== null) ? result : obj;
}
// 示例构造函数
function Person(name, age) {
this.name = name;
this.age = age;
} // 使用自定义的myNew方法创建对象实例 |
第22天 你对new操作符的理解是什么?手动实现一个new方法
The text was updated successfully, but these errors were encountered: