學了前端一段時間了,對js當時花了不少時間可是隨着後面學習框架有些就忘了。如今重新開始記錄下重要的知識點。有不少知識也是查閱js高程和別人的博客,所用的一些例子也是引用那些以爲頗有表明意義的,在文章最後貼出有關的博客。有錯的地方也請你們指出。有些知識深究的話我能力有限,也不知道;因此不少做爲一個結論記住就行。javascript
1.首先什麼是對象,什麼是函數對象。有些地方也叫函數,我查了下函數和函數對象應該是指代的同一個東西,沒有區別。首先前端
var a={"name":"hello"}; 這是一個普通的對象。 function f1(){}; var f2 = function(){}; 這是函數對象。那麼函數對象和對象又有什麼不一樣了。函數有個叫原型的東西是個對象,可是對象沒有。這裏引入了 prototype 這個屬性,那麼這個就是原型對象了,固然不是。它是個指針指向原型對象。這裏要記住prototype是個指針後面雖然還有繼承有關可是先記住是個指針。這裏就先說到這裏,區別函數對象和對象,以及一個重要屬性prototype,對象沒這個屬性。
java
2,那麼對象和函數對象又有什麼聯繫了,首先建立一個普通的對象var person = {}或者var 0=new object()。這是個普通的對象,經過這種字面量能夠創造不少單個對象。可是會產生大量重複代碼,因此有了工廠模式的出現。web
function creatPerson (name, age) { var person = new Object(); person.name = name; person.age = age; person.sayName = function () { alert(this.name); }; return person;
}
var person1= creatPerson ("tom",29)
他能建立一個包含一些信息的person對象,能夠屢次調用這個函數。可是卻沒有解決對象的識別問題(不知道這個對象的類型)。因此以後重頭戲來了,有了構造函數,這個知識點就涉及原型了。app
function CreatePerson(name, age, say){ this.name = name; this.age = age; this.say = say; this.should = function(){ console(this.say); } } var person1 = new CreatePerson("","","");
這個函數也很簡單,可是和以前的工廠模式有了些區別。這個函數有個很重要的 new 操做符。看一個實例:框架
function Animal(name){ this.name = name; } Animal.color = "black"; Animal.prototype.say = function(){ console.log("I'm " + this.name); }; var cat = new Animal("cat"); console.log( cat.color, //undefine cat.name //cat ); cat.say(); //I'm cat console.log( Animal.name, //Animal Animal.color //back ); Animal.say(); //Animal.say is not a function
這個函數沒看答案以前有可能你是不太清楚,可是看了答案你是應該是能得出一些結論的。雖然你可能不知道發生了什麼。首先 console.log( Animal.name, //Animal Animal.color //back ); 這個比較簡單沒什麼說的,不懂的函數的name屬性能夠看下。 cat.color, //undefine 這個是重點,這裏看的出來構造出來的實例並無繼承到color這個屬性,那麼就要引入構造函數的工做的模式了。關鍵的new字符,js高程是這麼解釋的:函數
1'建立一個新的對象;學習
2'將構造函數做用域賦給新的對象(即this指向新對象);this
3'執行構造函數裏面的代碼;spa
4'返回新的對象。
new Animal("cat") = { var obj = {}; obj.__proto__ = Animal.prototype; var result = Animal.call(obj,"cat");
//var result = obj.Animal("cat")。至關於Animal在obj做用域裏面運行
return typeof result === 'object'? result : obj; }
這是一個模仿new運行機制的僞代碼,這裏咱們看到一個新的東西出現了 __proto__ ,先給這個過程看完:obj的__proto__ 指向Animal的原型對象prototype而後你大概懂了
cat.say(); //I'm cat 以後,在obj對象的執行環境調用Animal函數並傳遞參數「cat」。 至關於var result = obj.Animal("cat")。 當這句執行完以後,obj便產生了屬性name並賦值爲"cat"。可能第二個你看的不太明白那你就能夠看看call屬性,以及this了。這裏先不提,後面能夠在仔細作下筆記。引入了__proto__ 那麼就至關於引入了原型鏈了,當你實例化一個對象,就會造成一個原型鏈,他會去找構造函數的prototype,而後逐級向上尋找,其實原型的重點是__proto__ ,我這裏將引入一兩道例題幫助本身記憶,以及本身的理解。
var animal = function(){}; var dog = function(){}; animal.price = 2000; dog.prototype = animal; var tidy = new dog(); //tidy.constructor=dog;實例tidy能夠經過受權找到它並用以檢測本身的構造函數 console.log(dog.price); //undefined console.log(tidy.price); // 2000
1'首先 dog.prototype = animal;這裏沒有問題的, 咱們能夠賦值任何類型的對象到原型上,可是不能賦值原子類型的值, 好比以下代碼是無效的: Foo.prototype = 1;
2'將 animal的值賦給dog的原型對象。 console.log(dog.price);針對這句代碼。首先是dog本身的自己的函數是沒price這個屬性的,而後原型上有,可是二者是沒有關係的。
3’ 它先經過查找自生,而後再循着__proto__去原型鏈中尋找,全局中也沒有,都沒有因此讀取不到price這個屬性。
var Animal = function(){}; Animal.prototype.say = function(){ alert("a"); }; Animal.say() //Animal.say s not a function
這個簡短的例子也是能說明問題的,而後在來看下面這個例子:
var animal = function(){}; var dog = function(){}; animal.price = 2000; dog.__proto__ = animal; var tidy = new dog(); console.log(dog.price) //2000 console.log(tidy.price) // undefined
1. dog.__proto__ = animal;直接找到 animal,獲取值dog.price==2000;
2. tidy.__proto__= dog.prototype;
3. tidy.__proto__.__proto__ === dog.prototype.__proto__=== Object.prototype;經過這個原型鏈確實找不到。這裏要區別prototype和__proto__
....................................................................................................................................................................................................................................................................
如今還有個constructor。,constructor始終指向建立當前對象的構造函數。
function Person(name,age){ this.name = name; this.age = age; } Person.prototype = { getName:function(){ return this.name; }, getAge:function(){ return this.age; } } var p = new Person("Nicholas",18); console.log(p.constructor); //Object()
這裏p.constructor不等於person是由於上面的給她至關於從new成一個新的對象
Person.prototype
=
new
Object({
getName:
function
(){
return
this
.name;
},
構造函數也是有 __proto__屬性的,而後也會造成一個原型鏈。
Constructor ----> Function.prototype ----> Object.prototype ----> null
function f()={};
var obj=new f();
這是一個普通實例的原型的原型鏈。
還有不少沒搞懂的,這部份內容確實多先到這吧,之後在慢慢更新。