JavaScript中new操作符的原理與實現(xiàn)詳解
一、new做了哪些事
先看看new的使用場景:
// 1、創(chuàng)建一個構造函數(shù) function Vehicle(name, price) { this.name = name this.price = price } ? // 2、new一個實例對象 let truck = new Vehicle() console.log(truck); //Vehicle { name: undefined, price: undefined } console.log(Object.prototype.toString.call(truck)); //[object Object] ? // 傳入?yún)?shù) let car = new Vehicle('car', '¥9999999') console.log(car); //Vehicle { name: 'car', price: '¥9999999' }
司空見慣的代碼,爛熟于心的寫法,那你知道new具體做了哪些事情嘛?從上述代碼可以看出,一個構造函數(shù)使用new操作符調用的時候,會生成一個具有構造函數(shù)相同屬性的新對象。是不是很奇怪?明明Vehicle是構造函數(shù):
console.log(typeof Vehicle); //function
然而,經(jīng)過new的一番操作后,它的實例化是一個對象!?。ew到底做了哪些事情呢?對于這個例子,我們可以概括為以下事情:
? // 第一件:在構造函數(shù)內部,創(chuàng)建一個this對象 let this = { name = name, price = price } ? // 第二件:返回this對象 return this; ? // 第三件:給this對象的屬性賦值 this.name = name this.price = price
很抽象,看不懂。。。進一步剖析如下:
function Person(name, gender) { console.log('賦值前的this=', this); //賦值前的this= Person {} this.name = name this.gender = gender console.log('賦值后的this=', this); //賦值后的this= Person { name: '小灰灰', gender: 'boy' } } ? let child = new Person('小灰灰', 'boy')//Person { name: '小灰灰', gender: 'boy' } console.log(child);
由以上代碼可以看出,
第一:在構造函數(shù)內部有一個空的this對象,通過new操作符,會創(chuàng)建生成一個全新的對象(實例對象)。
第二:實例對象會執(zhí)行[[Prototype]]( .proto)鏈接,并且實例對象的this會指向構造函數(shù)的this(實例對象會綁定函數(shù)調用的this)。通過new創(chuàng)建的實例對象最終被[[Prototype]]( .proto)鏈接到構造函數(shù)的Prototype對象上。也就是說,實例對象的隱式原型===構造函數(shù)的顯示原型
二、返回不同類型時有哪些表現(xiàn)
創(chuàng)建一個構造函數(shù)X,通過new操作符,實例化X得到實例化對象x,打印x,一定會是X{...}這個對象嘛?當構造函數(shù)內部有返回值,并且返回的是不同類型的值,打印的結果又會是怎么樣呢?
function Student(id, name) { this.id = id this.name = name ? // 返回基本類型的值時:返回的結果依然是對象Student {name:xxx,age:xxx} // return null //Student { id: '1001', name: 'cat' } // return undefined //Student { id: '1001', name: 'cat' } // return 123 //Student { id: '1001', name: 'cat' } // return 'hello world' //Student { id: '1001', name: 'cat' } // return true //Student { id: '1001', name: 'cat' } // return false //Student { id: '1001', name: 'cat' } //return Symbol('abc') //Student { id: '1001', name: 'cat' } ? // 返回引用類型時: //返回空對象時:返回的結果是空對象 // return {} //{} //返回函數(shù)時,返回的結果是函數(shù) return function() {} //[Function (anonymous)] // return [] //[] // return new Date() //2022-10-24T04:44:18.581Z // return new Error() //Error... } ? let student = new Student('1001', 'cat') console.log(student); //構造函數(shù)內部返回不同類型的值時,這里的打印結果是一樣的嗎?
三、手寫new的實現(xiàn)原理
思路:new的實現(xiàn)原理核心是new做了哪些事情。
總結:
(1)通過new操作符調用構造函數(shù),會返回一個全新的對象,這個對象的屬性是構造函數(shù)的參數(shù)。
若構造函數(shù)內部有返回值,且返回值是基本數(shù)據(jù)類型(number|string|null|undefined|Symbol|boolean),則實例對象的返回結果是原本的對象;
若返回值是引用數(shù)據(jù)類型(Object|Array|Function|Date|RegExp|Error),則實例對象的返回的結果就是引用類型對應的值。
(2)通過new操作符創(chuàng)建的實例對象的隱式原型會掛載到構造函數(shù)的顯示原型上。實例對象.proto==構造函數(shù).prototype。
(3)通過new操作符創(chuàng)建的實例對象的this會綁定調用函數(shù)的this 請看如下代碼:
// new的實現(xiàn)原理 function newPerson() { // 先return一個對象 var obj = {}; var constructor = Array.prototype.shift.call(arguments); //把數(shù)組的shift方法借給constructor使用 // 實例對象的隱式原型===構造函數(shù)的顯示原型 obj._proto_ = constructor.prototype; var result = constructor.apply(obj, arguments); return typeof result === 'object' && result != 'null' ? result : obj; } ? let p = newPerson(Person, 'hunny') console.log(p); //{ _proto_: {}, name: 'hunny', age: undefined }
以上就是JavaScript中new操作符的原理與實現(xiàn)詳解的詳細內容,更多關于JavaScript new操作符的資料請關注腳本之家其它相關文章!
相關文章
vant uploader實現(xiàn)上傳圖片拖拽功能(設為封面)
這篇文章主要介紹了vant uploader實現(xiàn)上傳圖片拖拽功能(設為封面),這個功能在日常生活中經(jīng)常會用到,操作非常方便,今天通過實例代碼介紹實現(xiàn)過程,需要的朋友可以參考下2021-10-10