当前位置:网站首页>The interviewer asked: can you simulate the new operator of JS
The interviewer asked: can you simulate the new operator of JS
2022-06-28 02:11:00 【InfoQ】
1. Preface
JS
new、call、apply、this、 Inherit
Interviewer asks series
Vuejs
new
new Vue({
el: '#app',
mounted(){},
});
new
new
2. new What did you do
// Example 1
function Student(){
}
var student = new Student();
console.log(student); // {}
// student It's an object .
console.log(Object.prototype.toString.call(student)); // [object Object]
// We know that we can also declare objects with new Object(); It just looks more complicated
// By the way `new Object`( Not recommended ) and Object() The same effect
// It can be guessed that an internal judgment has been made , use new call
/** if (!(this instanceof Object)) {
* return new Object();
* }
*/
var obj = new Object();
console.log(obj) // {}
console.log(Object.prototype.toString.call(student)); // [object Object]
typeof Student === 'function' // true
typeof Object === 'function' // true
new
Student
Object
Student
Object
JS

new Object()
new Student()
__proto__
constructor
Student
// in other words :
student.constructor === Student;
Student.prototype.constructor === Student;
2.1 Summary 1: From this simple example ,
new
The operator does two things :
- A new object is created .
- This object will be executed
[[Prototype]]
( That is to say__proto__
) link .
// Example 2
function Student(name){
console.log(' Before assignment -this', this); // {}
this.name = name;
console.log(' After the assignment -this', this); // {name: ' If Chuan '}
}
var student = new Student(' If Chuan ');
console.log(student); // {name: ' If Chuan '}
Student
this
new Student()
student
2.2 Summary 2: From this example ,
new
The operator does one more thing :
- The generated new object is bound to the function call
this
.
// Example 3
function Student(name){
this.name = name;
// this.doSth();
}
Student.prototype.doSth = function() {
console.log(this.name);
};
var student1 = new Student(' if ');
var student2 = new Student(' sichuan ');
console.log(student1, student1.doSth()); // {name: ' if '} ' if '
console.log(student2, student2.doSth()); // {name: ' sichuan '} ' sichuan '
student1.__proto__ === Student.prototype; // true
student2.__proto__ === Student.prototype; // true
// __proto__ It is the prototype scheme of browser implementation .
// use ES5 It is :
Object.getPrototypeOf(student1) === Student.prototype; // true
Object.getPrototypeOf(student2) === Student.prototype; // true


2.3 Summary 3: This example 3 Once again
Summary 1
Medium
The first 2 spot
. That is, the object will be executed
[[Prototype]]
( That is to say
__proto__
) link . And through
new Student()
Each object created will eventually be
[[Prototype]]
Link to this
Student.protytype
On the object .
// Example 4
function Student(name){
this.name = name;
// Null( empty ) null
// Undefined( Undefined ) undefined
// Number( Numbers ) 1
// String( character string )'1'
// Boolean( Boolean ) true
// Symbol( Symbol )( New in the sixth edition ) symbol
// Object( object ) {}
// Function( function ) function(){}
// Array( Array ) []
// Date( date ) new Date()
// RegExp( Regular expressions )/a/
// Error ( error ) new Error()
// return /a/;
}
var student = new Student(' If Chuan ');
console.log(student); {name: ' If Chuan '}
{name: ' If Chuan '}
Object
Functoin
Array
Date
RegExg
Error
2.4 The resulting Summary 4:
- If the function does not return an object type
Object
( containFunctoin
,Array
,Date
,RegExg
,Error
), thatnew
The function call in the expression automatically returns the new object .
- A new object is created .
- This object will be executed
[[Prototype]]
( That is to say__proto__
) link .
- The generated new object is bound to the function call
this
.
- adopt
new
Each object created will eventually be[[Prototype]]
Linked to this functionprototype
On the object .
- If the function does not return an object type
Object
( containFunctoin
,Array
,Date
,RegExg
,Error
), thatnew
The function call in the expression automatically returns the new object .
3. new Simulation Implementation
new
/**
* Simulation Implementation new The operator
* @param {Function} ctor [ Constructors ]
* @return {Object|Function|Regex|Date|Error} [ Return results ]
*/
function newOperator(ctor){
if(typeof ctor !== 'function'){
throw 'newOperator function the first param must be a function';
}
// ES6 new.target Is pointing to the constructor
newOperator.target = ctor;
// 1. Create a new object ,
// 2. And perform [[Prototype]] link
// 4. adopt `new` Each object created will eventually be `[[Prototype]]` Linked to this function `prototype` On the object .
var newObj = Object.create(ctor.prototype);
// ES5 arguments Turn it into an array You can also use it ES6 [...arguments], Aarry.from(arguments);
// remove ctor The rest of the arguments to the constructor
var argsArr = [].slice.call(arguments, 1);
// 3. The generated new object is bound to the function call `this`.
// Get ctor Function returns the result
var ctorReturnResult = ctor.apply(newObj, argsArr);
// Summary 4 Of these types, only Object and Function Two types of typeof null It's also 'object' So it's not equal to null, exclude null
var isObject = typeof ctorReturnResult === 'object' && ctorReturnResult !== null;
var isFunction = typeof ctorReturnResult === 'function';
if(isObject || isFunction){
return ctorReturnResult;
}
// 5. If the function does not return an object type `Object`( contain `Functoin`, `Array`, `Date`, `RegExg`, `Error`), that `new` The function call in the expression automatically returns the new object .
return newObj;
}
newOperator
// Example 3 Add one more parameter
function Student(name, age){
this.name = name;
this.age = age;
// this.doSth();
// return Error();
}
Student.prototype.doSth = function() {
console.log(this.name);
};
var student1 = newOperator(Student, ' if ', 18);
var student2 = newOperator(Student, ' sichuan ', 18);
// var student1 = new Student(' if ');
// var student2 = new Student(' sichuan ');
console.log(student1, student1.doSth()); // {name: ' if '} ' if '
console.log(student2, student2.doSth()); // {name: ' sichuan '} ' sichuan '
student1.__proto__ === Student.prototype; // true
student2.__proto__ === Student.prototype; // true
// __proto__ It is the prototype scheme of browser implementation .
// use ES5 It is :
Object.getPrototypeOf(student1) === Student.prototype; // true
Object.getPrototypeOf(student2) === Student.prototype; // true
new
new
newOperator
Object.create()
ES5
API
4. Object.create() Usage example
Object.create(proto, [propertiesObject])
undefined
var anotherObject = {
name: ' If Chuan '
};
var myObject = Object.create(anotherObject, {
age: {
value:18,
},
});
// Get its prototype
Object.getPrototypeOf(anotherObject) === Object.prototype; // true explain anotherObject The prototype is Object.prototype
Object.getPrototypeOf(myObject); // {name: " If Chuan "} // explain myObject The prototype is {name: " If Chuan "}
myObject.hasOwnProperty('name'); // false; explain name It's a prototype .
myObject.hasOwnProperty('age'); // true explain age It's self
myObject.name; // ' If Chuan '
myObject.age; // 18;
ES5
MDN
ployfill
if (typeof Object.create !== "function") {
Object.create = function (proto, propertiesObject) {
if (typeof proto !== 'object' && typeof proto !== 'function') {
throw new TypeError('Object prototype may only be an Object: ' + proto);
} else if (proto === null) {
throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
}
if (typeof propertiesObject != 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");
function F() {}
F.prototype = proto;
return new F();
};
}
5. So to conclude :
new
What did you do :
- A new object is created .
- This object will be executed
[[Prototype]]
( That is to say__proto__
) link .
- The generated new object is bound to the function call
this
.
- adopt
new
Each object created will eventually be[[Prototype]]
Linked to this functionprototype
On the object .
- If the function does not return an object type
Object
( containFunctoin
,Array
,Date
,RegExg
,Error
), thatnew
The function call in the expression automatically returns the new object .
- How to simulate
// Removed comments
function newOperator(ctor){
if(typeof ctor !== 'function'){
throw 'newOperator function the first param must be a function';
}
newOperator.target = ctor;
var newObj = Object.create(ctor.prototype);
var argsArr = [].slice.call(arguments, 1);
var ctorReturnResult = ctor.apply(newObj, argsArr);
var isObject = typeof ctorReturnResult === 'object' && ctorReturnResult !== null;
var isFunction = typeof ctorReturnResult === 'function';
if(isObject || isFunction){
return ctorReturnResult;
}
return newObj;
}
边栏推荐
- How fiddle uses agents
- [Niuke discussion area] Chapter 4: redis
- [Yocto RM]3 - Yocto Project Releases and the Stable Release Process
- 评价——秩和比综合评价
- fiddle如何使用代理
- ShardingSphere-proxy-5.0.0建立mysql读写分离的连接(六)
- 1382. balancing binary search tree - General method
- To understand what is synchronous, asynchronous, serial, parallel, concurrent, process, thread, and coroutine
- Self supervised learning and drug discovery
- Adobe Premiere基础-常用的视频特效(边角定位,马赛克,模糊,锐化,手写工具,效果控件层级顺序)(十六)
猜你喜欢
Hi, you have a code review strategy to check!
Intranet penetration with FRP
The research group of Xuyong and duanwenhui of Tsinghua University has developed an efficient and accurate first principles electronic structure deep learning method and program
Adobe Premiere foundation - sound adjustment (volume correction, noise reduction, telephone tone, pitch shifter, parameter equalizer) (XVIII)
药物发现综述-03-分子设计与优化
基于AM335X开发板 ARM Cortex-A8——Acontis EtherCAT主站开发案例
[elt.zip] openharmony paper Club - memory compression for data intensive applications
How to optimize the "message" list of IM
ShardingSphere-proxy-5.0.0建立mysql读写分离的连接(六)
Numpy----np.reshape()
随机推荐
Coscon'22 lecturer solicitation order
树莓派实现温控风扇智能降温
Intranet penetration with FRP
JS 随机数(随机数 小数)
frp实现内网穿透
Cesium 点击绘制多边形(动态绘制多边形)
Scala 基础 (三):运算符和流程控制
评价——秩和比综合评价
Review of drug discovery-03-molecular design and optimization
Lmsoc: a socially sensitive pre training method
Take n multiple table names of a database as the values of a column in another table (the range can be a table in another database)
引用层reboot后的大体流程
Centos8 operation record command version Yum redis MySQL Nacos JDK
嵌入式必学,硬件资源接口详解——基于ARM AM335X开发板 (上)
【嵌入式基础】串口通信
[Yocto RM]1 - System Requirements
Numpy----np. meshgrid()
geojson 格式說明(格式詳解)
Shardingsphere-proxy-5.0.0 establish MySQL read / write separation connection (6)
Numpy----np.meshgrid()