JavaScript對象,函數,prototype,constructor總結

最近看前端代碼學習js和react,本來覺得基本的Js語法會就可以了,但是感覺這樣學習react是真的吃力還混淆。所以閱讀了一些博客寫一點參考的學習心得。只記錄混淆部分,如果有和我一樣迷糊的人可以看看。這篇是一邊看博客一邊寫代碼測試的,感覺準確度應該沒啥問題
ps:是__proto__ 但是由於markdown顯示,可能有的地方是proto
學習資料:
http://reng99.cc/2018/04/05/prototype-object-chain-md/
https://developer.mozilla.org/zhCN/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor
https://www.cnblogs.com/jikey/archive/2010/04/28/1722971.html

函數是特殊的對象

var str="js is so interesting";
var num=10;
var arr=new Array();
var obj={degree:"hard"};
function f(){};
var ff=new f();
//他們是什麼類型?內置類型,函數類型等
typeof(str);//string
typeof(num);//number
typeof(arr);//object,這裏Array需要注意同時多看
typeof(obj);//object
typeof(f);//function
typeof(ff);//object

思考:從typeof看函數定義的對象和函數作爲構造函數構造的對象他們的類型,來區分這兩個看起來很像但是完全不一樣的對象
function f(){…}函數對象,本質函數,構造函數Function()。這是第一層,constructor指向構造函數,有prototype屬性,指向prototype對象
var ff=new f();函數作爲構造函數,new構建返回一個對象。沒有prototype屬性,constructor指向構造函數,即f,這是第二層

typeof(Function);//function 對象構造器
typeof(new Function());//function!!! 
typeof(new f());//object
typeof(Array);//function 對象構造器
typeof(Object);//function 對象構造器
typeof(new Object());//object

體會對象構造器,以及函數是特殊的對象。new 函數返回的是函數,同時構造函數也是Function( )

constructor屬性的理解

//關於constructor的理解:constructor屬性值是對構造函數的引用
console.log(str.constructor);//function String(){[native code]}
console.log(num.constructor);//function Number(){[native code]}
console.log(arr.constructor)//function Array(){[native code]}
console.log(obj.constructor);//function Object(){[native code]}
console.log(f.constructor);//他是函數!function Function(){[native code]}
console.log(ff.constructor);//他是對象,構造函數是一個函數對象!//function f(){}

constructor屬性指向自己的構造函數。
Number:1,String:“test”,Boolean:true的constructor屬性值是隻讀的,無法修改。

prototype屬性的理解

console.log(str.prototype);//undefined 說明一般對象並沒有這個屬性,他們有__proto__
console.log(num.prototype);//undefined 說明一般對象並沒有這個屬性,他們有__proto__
console.log(arr.prototype);//undefined 說明一般對象並沒有這個屬性,他們有__proto__
console.log(obj.prototype);//undefined 說明一般對象並沒有這個屬性,他們有__proto__
console.log(f.prototype);//[Object Object] 
console.log(ff.prototype);//undefined
console.log(f.prototype.constructor);//function f(){}三者關係
console.log(ff.constructor===f.prototype.constructor)//true

對prototype屬性的理解
對prototype屬性的理解:prototype屬性,是函數獨有的,因爲當你用function f(){}定義得到一個函數,此時爲這個函數添加這個屬性,這個屬性指向prototype對象。prototype對象裏包含constructor屬性,這個屬性保存指向函數的一個引用
就像是繞了一圈又回來了f.prototype.constructor指向自己==ff.constructor

對__proto__屬性的理解

首先擁有prototype這個屬性的有:Function String,Number,Object,function f(){…}…其他都是undefined,用hasOwnProperty(“prototype”)也是false
官方定義了所有對象除了null擁有prototype屬性,這個屬性指向原型對象的內存堆,遞歸,形成原型鏈,最終指向Object.prototype但是用__proto__來訪問這個屬性,這是瀏覽器做的一種實現,用hasOwnProperty(“proto”)也是false
此處思考:
__proto__與prototype這兩個屬性的關係?
擁有者?
含義?

console.log(typeof(str.__proto__));//object
console.log(str.__proto__===String.prototype);//true
console.log(str.__proto__===Object.prototype);//false
console.log(typeof(num.__proto__));//object
console.log(num.__proto__===Number.prototype);//true
console.log(num.__proto__===Object.prototype);//false
console.log(typeof(arr.__proto__));//object
console.log(arr.__proto__===Array.prototype);//true
console.log(arr.__proto__===Object.prototype);//false
console.log(typeof(obj.__proto__));//object
console.log(obj.__proto__===Object.prototype);//true
console.log(obj.hasOwnProperty('prototype'));//false
console.log(obj.hasOwnProperty('__proto__'));//false
console.log(typeof(f.__proto__));//function 再次體現函數的特殊 指向原型對象Function
console.log(f.__proto__===Function.prototype);//true
console.log(f.__proto__===Object.prototype);//false
console.log(f.__proto__.__proto__===Object.prototype);//true
console.log(typeof(ff.__proto__));//object 
console.log(ff.__proto__===Function.prototype);//false
console.log(ff.__proto__===Object.prototype);//false
console.log(ff.__proto__===f.prototype);//true 破案了!!! 他的原型對象是構造他的函數對象!!!
//f.prototype又指向f的prototype對象

__proto__指向構造函數的原型對象,這個屬性值的type是對象,他是什麼類型就指向什麼xxx.prototype,xxx是其構造函數!
Xxx.prototype在我看來就是指Xxx這個類型,這個原型
console.log(ff.proto===f.prototype);
構造函數是f,指向構造函數的原型對象,剛好函數是有prototype屬性,prototype屬性指向prototype對象。所以即f.prototype

原型鏈

//原型對象之間的關係
console.log(String.prototype.__proto__===Object.prototype);//true 
//所以怎麼理解String.prototype,他是一個對象,他是原型對象,用__proto__屬性指向他的原型
console.log(Number.prototype.__proto__===Object.prototype);//true 
console.log(Array.prototype.__proto__===Object.prototype);//true 
console.log(Object.prototype.__proto__===Object.prototype);//false 
console.log(Function.prototype.__proto__===Object.prototype);//true
console.log(Object.prototype.hasOwnProperty('__proto__')); // true
console.log(Object.prototype.__proto__===null); // true

從這也看出各類型之間的關係了。終點是Object.prototype(其實是null,從無到有,到萬物。停在最初的Object.prototype就好)

現在總結一下這幾小段學習:

  1. prototype屬性都有誰擁有?
    函數,String,Object…
  2. 如何理解prototype屬性?xxx.原型對象我覺得就是指這個類型的原型,可以理解爲這個類型
    String.prototype=String這個類型
    理解爲自己這個類型(原型)
    不過函數的prototype要重點理解一下,真的很難理解!但是一定要記住。他只想原型對象,這個對象很迷,這個對象的構造函數又指向自己
function f(){};
var f1=new f();
console.log((f.prototype.constructor));//function f(){}
console.log(Function.prototype.constructor)
//function Function() { [native code] }
console.log(f1.prototype);//undefined
  1. 如何理解__proto__屬性?
    指向原型對象,typeof(屬性值)是Object或Function(因爲原型是函數或者某個類型,再次驗證了函數是特殊的對象!!!)
    new生成的類型.prototype=這個對象.proto
    說出以下幾個對象的原型鏈:
function f(){}
// Function.prototype——>Object.prototype
var f1=new f();
//f.prototype——>Function.prototype——>Object.prototype
var str="sss";
//String.prototype——>Object.prototype

讀取實例的屬性

沿着原型鏈,從實例到原型…一直查找
這裏借用博客一位大神的代碼和圖總結,簡單易懂

function Person(name){
	this.name = name;
}
Person.prototype.sayName = function(){
	console.log(this.name);
}

var person = new Person("嘉明");
person.age = 12;
person.sayName(); // "嘉明"
console.log(person.name.toString()); // "嘉明"

var another_person = new Person("jiaming");
another_person.sayName();

在這裏插入圖片描述

摘抄一些博客裏非常經典的幾句

Function是所有函數對象的基礎,而Object則是所有對象(包括函數對象)的基礎。在JavaScript中,任何一個對象都是Object的實例,因此,可以修改Object這個類型來讓所有的對象具有一些通用的屬性和方法,修改Object類型是通過prototype來完成的。(我的理解:他是在原型上修改,通用,且對所有)

當談到繼承時,JavaScript 只有一種結構:對象。每個實例對象( object )都有一個私有屬性(稱之爲 proto )指向它的構造函數的原型對象(prototype )。該原型對象也有一個自己的原型對象( proto ) ,層層向上直到一個對象的原型對象爲 null。根據定義,null 沒有原型,並作爲這個原型鏈中的最後一個環節。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章