摘要:一旦原型對(duì)象被賦予屬性和方法那么由相應(yīng)的構(gòu)造函數(shù)創(chuàng)建的實(shí)例會(huì)繼承上的屬性和方法為什么只有函數(shù)才有屬性規(guī)范就這么定的。其它的構(gòu)造器的都是一個(gè)對(duì)象。
哪些對(duì)象有原型?
所有的對(duì)象在默認(rèn)情況下都有一個(gè)原型,因?yàn)樵捅旧硪彩菍?duì)象,所以每個(gè)原型自身又有一個(gè)原型(只有一種例外,默認(rèn)的對(duì)象原型在原型鏈的頂端)
prototype屬性
prototype是每個(gè)函數(shù)對(duì)象都具有的屬性,被稱為原型對(duì)象,而__proto__屬性才是每個(gè)對(duì)象才有的屬性。一旦原型對(duì)象被賦予屬性和方法,那么由相應(yīng)的構(gòu)造函數(shù)創(chuàng)建的實(shí)例會(huì)繼承prototype上的屬性和方法
為什么只有函數(shù)才有prototype屬性?ES規(guī)范就這么定的。
當(dāng)你創(chuàng)建函數(shù)時(shí),JS會(huì)為這個(gè)函數(shù)自動(dòng)添加prototype屬性, 值是一個(gè)有 constructor 屬性的對(duì)象,不是空對(duì)象。而一旦你把這個(gè)函數(shù)當(dāng)作構(gòu)造函數(shù)(constructor)調(diào)用(即通過new關(guān)鍵字調(diào)用),那么JS就會(huì)幫你創(chuàng)建該構(gòu)造函數(shù)的實(shí)例,實(shí)例繼承構(gòu)造函數(shù)prototype的所有屬性和方法(實(shí)例通過設(shè)置自己的__proto__指向承構(gòu)造函數(shù)的prototype來實(shí)現(xiàn)這種繼承)
constructor屬性和prototype屬性
每個(gè)函數(shù)都有prototype屬性,而這個(gè)prototype的constructor屬性會(huì)指向這個(gè)函數(shù)。
proto
對(duì)象__proto__屬性的值就是它所對(duì)應(yīng)的原型對(duì)象
var one = {x: 1}; var two = new Object(); one.__proto__ === Object.prototype // true two.__proto__ === Object.prototype // true one.toString === one.__proto__.toString // true
下面我們來看個(gè)例子來幫助理解這三個(gè)屬性
function Person(name){ this.name = name; } var p1 = new Person("louis"); console.log(Person.prototype);//Person原型 {constructor: Person(name),__proto__: Object} console.log(p1.prototype);//undefined console.log(Person.__proto__);//空函數(shù), function(){} console.log(p1.__proto__ == Person.prototype);//true
我們發(fā)現(xiàn), Person.prototype(原型) 默認(rèn)擁有兩個(gè)屬性:
constructor 屬性, 指向構(gòu)造器, 即Person本身
proto 屬性, 指向一個(gè)空的Object 對(duì)象
而p1作為非函數(shù)對(duì)象, 自然就沒有 prototype 屬性
下面來看看__proto__屬性:
p1.__proto__ 屬性 指向的是 構(gòu)造器(Person) 的原型, 即 Person.prototype.
這里我們發(fā)現(xiàn): 原型鏈查詢時(shí), 正是通過這個(gè)屬性(__proto__) 鏈接到構(gòu)造器的原型, 從而實(shí)現(xiàn)查詢的層層深入.
Person.__proto__ 屬性 指向的是一個(gè)空函數(shù)( function(){} ),
console.log(Person.__proto__ === Function.prototype);//true
Person 是構(gòu)造器也是函數(shù)(function), Person的__proto__ 屬性自然就指向 函數(shù)(function)的原型, 即 Function.prototype.
這說明 所有的構(gòu)造器都繼承于Function.prototype
既然所有的構(gòu)造器都來自于Function.prototype, 那么Function.prototype 到底是什么呢?
我們借用 typeof 運(yùn)算符來看看它的類型.
console.log(typeof Function.prototype) // "function"
實(shí)際上, Function.prototype也是唯一一個(gè)typeof XXX.prototype為 “function”的prototype。其它的構(gòu)造器的prototype都是一個(gè)對(duì)象。如下:
console.log(typeof Number.prototype) // object console.log(typeof Boolean.prototype) // object console.log(typeof String.prototype) // object console.log(typeof Object.prototype) // object console.log(typeof Array.prototype) // object console.log(typeof RegExp.prototype) // object console.log(typeof Error.prototype) // object console.log(typeof Date.prototype) // object
既然Function.prototype 的類型是函數(shù), 那么它會(huì)擁有 proto 屬性嗎, Function.prototype.__proto__ 會(huì)指向哪里呢? 會(huì)指向?qū)ο蟮脑蛦? 請(qǐng)看下方:
console.log(Function.prototype.__proto__ === Object.prototype) // true
透過上方代碼, 且我們了解到: Function.prototype 的類型是函數(shù), 也就意味著一個(gè)函數(shù)擁有 proto 屬性, 并且該屬性指向了對(duì)象(Object)構(gòu)造器的原型. 這意味著啥?
根據(jù)我們?cè)谇懊媪私獾降? proto 是對(duì)象的內(nèi)部屬性, 它指向構(gòu)造器的原型.
這意味著 Function.prototype 函數(shù) 擁有了一個(gè)對(duì)象的內(nèi)部屬性, 并且該屬性還恰好指向?qū)ο髽?gòu)造器的原型. 它是一個(gè)對(duì)象嗎? 是的, 它一定是對(duì)象. 它必須是.實(shí)際上, JavaScript的世界觀里, 函數(shù)也是對(duì)象, 函數(shù)是一等公民.
這說明所有的構(gòu)造器既是函數(shù)也是一個(gè)普通JS對(duì)象,可以給構(gòu)造器添加/刪除屬性等。同時(shí)它也繼承了Object.prototype上的所有方法:toString、valueOf、hasOwnProperty等。
Object.prototype
函數(shù)的 proto 屬性指向 Function.prototype, 如: Person.__proto__ —> Function.prototype
Function.prototype 函數(shù)的 proto 屬性指向 Object.prototype, 如: Function.prototype.__proto__ —> Object.prototype.
那么Object.prototype.__proto__ 指向什么呢?
console.log(Object.prototype.__proto__ === null);//true
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/96325.html
摘要:寫在前面如果說是一本武學(xué)典籍,那么原型鏈就是九陽神功。那么,如何修煉好中的九陽神功呢真正的功法大成的技術(shù)是從底層上去理解,那種工程師和碼農(nóng)的區(qū)別就在于對(duì)底層的理解,當(dāng)你寫完一行代碼,或者你遇見一個(gè)解決的速度取決于你對(duì)底層的理解。 寫在前面 如果說JavaScript是一本武學(xué)典籍,那么原型鏈就是九陽神功。在金庸的武俠小說里面,對(duì)九陽神功是這樣描述的:練成「九陽神功」后,會(huì)易筋洗髓;生出...
摘要:寫在前面如果說是一本武學(xué)典籍,那么原型鏈就是九陽神功。那么,如何修煉好中的九陽神功呢真正的功法大成的技術(shù)是從底層上去理解,那種工程師和碼農(nóng)的區(qū)別就在于對(duì)底層的理解,當(dāng)你寫完一行代碼,或者你遇見一個(gè)解決的速度取決于你對(duì)底層的理解。 寫在前面 如果說JavaScript是一本武學(xué)典籍,那么原型鏈就是九陽神功。在金庸的武俠小說里面,對(duì)九陽神功是這樣描述的:練成「九陽神功」后,會(huì)易筋洗髓;生出...
摘要:寫在前面如果說是一本武學(xué)典籍,那么原型鏈就是九陽神功。那么,如何修煉好中的九陽神功呢真正的功法大成的技術(shù)是從底層上去理解,那種工程師和碼農(nóng)的區(qū)別就在于對(duì)底層的理解,當(dāng)你寫完一行代碼,或者你遇見一個(gè)解決的速度取決于你對(duì)底層的理解。 寫在前面 如果說JavaScript是一本武學(xué)典籍,那么原型鏈就是九陽神功。在金庸的武俠小說里面,對(duì)九陽神功是這樣描述的:練成「九陽神功」后,會(huì)易筋洗髓;生出...
摘要:創(chuàng)建對(duì)象與工廠模式的區(qū)別沒有顯示地創(chuàng)建對(duì)象直接將方法和屬性付給了對(duì)象沒有語句構(gòu)造函數(shù)應(yīng)該始終以一個(gè)大寫字母開頭。創(chuàng)建構(gòu)造函數(shù)的實(shí)例,必須使用操作符。 構(gòu)造函數(shù)模式 ECMAScript中的構(gòu)造函數(shù)可用來創(chuàng)建特定類型的對(duì)象,像Object和Array這樣的原生構(gòu)造函數(shù)。也可以創(chuàng)建自定義的構(gòu)造函數(shù),從而定義自定義對(duì)象類型的屬性和方法。 1.創(chuàng)建對(duì)象 function Person(name...
閱讀 955·2019-08-30 14:24
閱讀 987·2019-08-30 14:13
閱讀 1799·2019-08-29 17:21
閱讀 2661·2019-08-29 13:44
閱讀 1654·2019-08-29 11:04
閱讀 438·2019-08-26 10:44
閱讀 2564·2019-08-23 14:04
閱讀 908·2019-08-23 12:08