JavaScript面向對象主要知識點小結,基於ECMAScript 5.javascript
function People(name){ //this能夠理解爲經過new即將建立的對象 this.name = name; } //將類實例化 var person = new People('Cassie Xu'); console.log(person.name);
給一個對象賦予屬性或者方法java
function People(name) { this.name = name; this.greet = function() { console.log('Hello, my name is ' + this.name + '!'); }; } var person = new People('Cassie Xu'); person.greet();
why we use prototype? -> 便於方法的重用
與構造函數模式相比,使用原型對象的好處是能夠讓全部對象實例共享它所包含的屬性和方法。
運行時沒找到函數的方法時,對象會首先找它的類的prototype方法
Demo1git
function People(name) { this.name = name; } People.prototype = { greet: function() { console.log('Hello, my name is ' + this.name + '!'); } }; var person = new People('Cassie Xu'); person.greet(); //在每一個實例化後的對象都會有一個__proto__屬性,類會將它的prototype賦給實例 //實例化一個對象時,People這個類首先會將person的__proto屬性指向People.prototype console.log(person.__proto__ === People.prototype); // true
Demo2github
var a = { foo: 1 }; var b = { bar: 2 }; b.__proto__ = a; //b自己沒有foo屬性,可是b會繼續尋找__proto__屬性 console.log(b.foo); // 1 console.log(b.bar); // 2 var a = {}; console.log(a.__proto__); // {} console.log(a.__proto__.__proto__); // null
var a = {}; console.log(a.__proto__); // {} console.log(a.__proto__.__proto__); // null
Demo1數組
function Parent(){} Parent.prototype = { greet: function(){ console.log('hello world'); } } function Child(){} //此方法適用於父類Child不須要傳參數 Child.prototype = new Parent(); var c = new Child(); //c首先尋找自身的方法,沒有great,因此找Child的原型方法,而Child.prototype等於Parent方法 c.greet(); //console.log('hello world');
上面的例子若是Parent有參數,將存在如下問題:閉包
function Parent(a, b) {} Parent.prototype.greet = function() { console.log('JavaScript rocks'); } function Child(a, b) {} Child.prototype = new Parent(); //something wrong?->new Parent()不能傳參數,不然參數一直不變 var child = new Child(); child.greet();
Demo2
解決父類參數問題app
function Parent() { this.name = 'xxx', this.date = 'xxx' } Parent.prototype.greet = function() { console.log('JavaScript rocks'); } function Child() {} //此方法適用於 Child.prototype = Object.create(Parent.prototype); //硬記的知識 Child.prototype.constructor = Child; var child = new Child(); child.greet();
Demo3:繼承的一個實例
建立一個矩形dom
function Rect(width,height){ this._setupDOM(width,height); } Rect.prototype._setupDOM = function(width,height){ this._dom = document.createElement('div'); this._dom.style.width = width + 'px'; this._dom.style.height = height + 'px'; }; Rect.prototype.appendToBody = function(){ document.body.appendChild(this._dom); }; function BlueRect(width,height){ BlueRect._super.apply(this,arguments); } BlueRect.prototype = Object.create(Rect.prototype); BlueRect.prototype.constructor = BlueRect; BlueRect._super = Rect; BlueRect.prototype._setupDOM = function(width,height){ BlueRect._super.prototype._setupDOM.apply(this,arguments); this._dom.style.backgroundColor = 'blue'; }; var br = new BlueRect(200,300); br.appendToBody();
Demo:函數
function Rect(width,height){ //私有屬性加_ this._dom = document.createElement('div'); this._dom.style.width = width + 'px'; this._dom.style.height = height + 'px'; this._dom.style.backgroundColor = 'red'; } Rect.prototype.appendToBody = function(){ document.body.appendChild(this._dom); }; var rect = new Rect(100,100); rect.appendToBody();
修改上面demo:this
function Rect(width,height){ this._setupDom(width,height); } Rect.prototype._setupDom = function(width,height){ //私有屬性加_ this._dom = document.createElement('div'); this._dom.style.width = width + 'px'; this._dom.style.height = height + 'px'; this._dom.style.backgroundColor = 'red'; }; Rect.prototype.appendToBody = function(){ document.body.appendChild(this._dom); }; var rect = new Rect(100,100); rect.appendToBody(); var person = { firstName: "Penelope", lastName: "Barrymore", sayFullName: function () { console.log(this.firstName + " " + this.lastName); //=> "Penelope Barrymore" console.log(person.firstName + " " + person.lastName); //=> "Penelope Barrymore" } }; person.sayFullName();
嚴格模式下的this
funtion foo(){ 'use strict'; console.log(this) //undefined }
function foo(a, b) { console.log(this); console.log(a + b); } var fooBinding = foo.bind({ name: 'Cassie Xu' }); fooBinding(1, 2);
上面code將輸出
[object Object] { name: "Cassie Xu" }
call/apply方法都爲調用Object方法,區別是apply將全部參數放到一個數組中去
function foo(a, b) { console.log(this); console.log(a + b); } foo.call({name:'Cassie Xu'}, 1, 2); foo.apply({name:'Cassie Xu'}, [1, 2]);
why we use it? ->避免泄露全局變量
(function(c){ var a = 1; var b = 2; console.log(a+b+c); })(3) // c = 3
var a = {}; a.foo = function(callback) { // do something and call callback in whatever way } a.bar = function() { this.num = 1; var that = this; //閉包,這裏that能夠訪問到a.bar的做用域 this.foo(function(newNum) { that.num = newNum; }); console.log(this.num); } a.bar();
本文轉自 JavaScript面向對象知識點小結