打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
js 對象、原型、繼承詳解

對象

對象分普通對象和函數對象,ObjectFunction是js自帶的函數對象。

function f1(){};var f2 = function(){};var f3 = new Function('str','console.log(str)');var o3 = new f1();var o1 = {};var o2 = new Object();console.log(typeof Object); //functionconsole.log(typeof Function); //functionconsole.log(typeof o1); //objectconsole.log(typeof o2); //objectconsole.log(typeof o3); //objectconsole.log(typeof f1); //functionconsole.log(typeof f2); //functionconsole.log(typeof f3); //function 

以上例子說明:凡是通過 new Function() 創建的對象都是函數對象,其他的都是普通對象。 FunctionObject 也都是通過new Function()創建的。

原型

js中所有的__函數__都有一個prototype屬性,這個屬性引用了一個對象,即原型對象,也簡稱原型。
這個_函數_包括構造函數和普通函數,我們講的更多是構造函數的原型,但是也不能否定普通函數也有原型。

註:普通對象沒有prototype屬性,但有內置屬性:__proto__(可以在chrome中查看該屬性,但不要依賴使用此屬性)。

譬如普通函數:

function f(){    //...}alert(f.prototype instanceof Object) //true

構造函數,也叫構造對象。首先瞭解下通過構造函數實例化對象的過程。

function A(x){    this.x=x;}var a = new A(1);

new

new也就是實例化對象,過程有如下幾步:

  1. 創建對象o;var o = {};
  2. o內部的__proto__對象的引用指向o的構造函數A的原型對象(A.prototype)。
  3. o作為this去調用構造函數A,從而設置o的屬性和方法並初始化。

傳送門:模擬new操作符的內部處理過程

當這3步完成,這個o對象就與構造函數A再無聯繫,這個時候即使構造函數A再加任何成員,都不再影響已經實例化的o對象了。
此時,o對象具有了x屬性,同時具有了構造函數A的原型對象的所有成員,當然,此時該原型對象是沒有成員的。

原型對象初始是空的,也就是沒有一個成員(即原型屬性和原型方法)。可以通過如下方法驗證原型對象具有多少成員。

function A(name){    this.name = name;}var num = 0;A.prototype.say = function(){    alert("Hi")};for(i in A.prototype){    console.log(i);  //say    num++;}console.log("member: " + num); // 1

解釋了什麼是原型對象,我們再來看看它的作用是什麼,先看一段代碼:

function Person(name){    this.name = name;}Person.prototype.getName = function(){    return this.name;}var o = new Person('chan');o.getName(); // chan

可以看到,通過給Person.prototype設置一個方法getName,實例後的對象o也會繼承這個方法。具體怎麼實現的繼承,需講到下面的原型鏈。

原型鏈

js在創建對象(無論是普通對象還是函數對象)的時候,都有一個叫做__proto__的內置屬性,用於指向創建它的函數對象的原型對象prototype

原型鏈的基本思想是利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。

簡單回顧下構造函數、原型和實例的關係:

每個構造函數都有一個原型對象,原型對象包含一個指向構造函數的指針(prototype),而實例則包含一個指向原型對象的內部指針(__proto__)。

以下面的例子為例:

function Person(name){    this.name = name;}Person.prototype.getName = function(){    return this.name;}var o = new Person('chan');o.getName(); // chanconsole.log(o.__proto__ === Person.prototype) //true

Person.prototype對象也有__proto__屬性,它指向創建它的函數對象(Object)的 prototype

console.log(Person.prototype.__proto__ === Object.prototype) //true

繼續,Object.prototype對象也有__proto__屬性,但它比較特殊,為null

console.log(Object.prototype.__proto__) //null

原型鏈如下圖:

疑點解釋:
Object.__proto__ === Function.prototype // true     Object是函數對象,是通過new Function()創建,所以Object.__proto__指向Function.prototype。Function.__proto__ === Function.prototype // true   Function 也是對象函數,也是通過new Function()創建,所以Function.__proto__指向Function.prototype。Function.prototype.__proto__ === Object.prototype //true   Function.prototype是個函數對象,理論上他的__proto__應該指向 Function.prototype,就是他自己,自己指向自己,沒有意義。

js一切皆為對象,原型鏈的最頂層為null,即Object.prototype.__proto__ === null

instanceof

//demo[1,2] instanceof Array  //truenew Object() instanceof Array  //false[1,2] instanceof Object  //true

左側一般是一個對象,右側一定是個函數對象,不是函數對象會報錯。

原理:右側函數的prototype屬性是否出現在左側對象的原型鏈上。即:左側的原型鏈上是否有右側的原型。

constructor

原型對象prototype中都有預定義的constructor,用來指向它的構造函數。

o.prototype.constructor === Person //trueFunction.prototype.constructor === Function //trueObject.prototype.constructor === Object //true

繼承

因為ECMAscript的發明者為了簡化這門語言,同時又保持繼承性,採用了鏈式繼承的方法。
由構造函數創建的每個實例都有個__proto__屬性,它指向構造函數的prototype。那麼構造函數的prototype上定義的屬性和方法都會被instance所繼承.

function Person(){	//...}function Student(){	//...}Student.prototype = Person.prototype;	//不可以這樣繼承,改變Student的同時,也會改變Person,因為他們是引用Student.prototype = new Person();	//可以實現 new Person的時候得到了Person的實例,並且Person的實例指向了Person.prototype 並且調用了構造函數。不過因為調用了構造函數,在Person有參數時此方法不太好使//僅ES5+支持Student.prototype = Object.create(Person.prototype);	//Object.create的作用:創建以個空對象,並且這個空對象的原型指向傳入的參數,即Person.prototypeStudent.prototype.constructor = Person;if(!Object.create){	//proto 為原型對象	Object.create = function(proto){		function F(){};		F.prototype = proto;		return new F;	}}


參考自:

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
js原型与原型链的详细理解
JS原型与原型链终极详解
ECMAScript:原型链 (prototype 与
js原型原型链
三张图搞懂JavaScript的原型对象与原型链
JS类型判断typeof PK {}.toString.call(obj)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服