JavaScript面向對象知識點小結

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();

原型(prototype)

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

原型鏈(prototype chain)

var a = {};
console.log(a.__proto__); // {}
console.log(a.__proto__.__proto__); // null

繼承(Inheritance)

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();

this關鍵字

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
}

強制修改函數上下文的方法

用Object.bind()代替this

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"
}

使用Object.call/Object.apply執行上下文

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面向對象知識點小結

相關文章
相關標籤/搜索