javascript之面向對象

建立對象

一、姿式一函數

var person = new object();
person.name = 'jack'
person.age = 18;

person.sayName = function(){
    console.log(this.name);

二、姿式二(簡單方便,推薦使用)this

var person = {
    name: 'jack',
    age: 18,
    sayName: function(){
        console.log(this.name);
    }
}

構造函數

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

var p1 = new Person('jack', 18);
p1.sayName(); // jack

構造函數和實例對象的關係

在每個實例對象中同時有一個constructor屬性,該屬性指向建立該實例的構造函數prototype

function Person(name, age){
    this.name = name,
    this.age = age,
    this.sayName = function(){
        console.log('i am ' + this.name);
    }
};
var p1 = new Person('alex', 18);
var p2 = new Person('jason', 17);
console.log(p1.constructor === Person); // true
console.log(p1.constructor === p2.constructor); //true

檢測對象類型,使用instanceof更加靠譜指針

console.log(p1 instanceof Person); //true
console.log(p2 instanceof Person); //true

對於每個實例來講,sayName都是如出一轍的內容每一次生成一個實例,都必須爲重複的內容,多佔用一些內存,若是實例對象不少,會形成極大的內存浪費code

var fns = {
    sayName: function(){
        console.log("i am" + this.name);
    }
}

function Person(name, age){
    this.name = name,
    this.age = age,
    this.sayName = fns.sayName
}

var p1 = new Person('alex', 18);
p1.sayName();

上述方法解決了內存浪費的問題,可是看起來不夠優雅,終極解決方法prototype對象

原型

JavaScript 規定,每個構造函數都有一個 prototype 屬性,指向另外一個對象。ip

function F(){};
console.log(F.prototype) // Object

構造函數的 prototype 對象默認都有一個 constructor 屬性,指向 prototype 對象所在函數。內存

console.log(F.prototype.constructor === F) // => true

經過構造函數獲得的實例對象內部會包含一個指向構造函數的 prototype 對象的指針 proto原型

var instance = new F()
console.log(instance.__proto__ === F.prototype) // => true

這也就意味着,咱們能夠把全部對象實例須要共享的屬性和方法直接定義在 prototype 對象上。io

function Person(name, age){
    this.name = name
    this.age = age
}
Person.prototype.type = 'human';
Person.prototype.sayName = function(){
    console.log(this.name);
}
var p1 = new Person('alex', 18);
var p2 = new Person('jack', 18);
console.log(p1.sayName === p2.sayName); //true

構造函數、實例、原型三者之間的關係

image

注意:

"contructor"並不表示(對象)被(它)構造

p1.contructor只是經過默認的[[Prototype]]委託指向Person和「構造」毫無關係。Person.prototype的。contructor屬性只是Person函數聲明時的默認屬性

function Person(name, age){
    this.name = name,
    this.age = age,
    this.sayName = function(){
        console.log('i am ' + this.name);
    }
};
function Test(){
    this.name = 'test';
}
Person.prototype = {
    constructor: Test
}
var p1 = new Person('alex', 18);
console.log(p1.constructor === Person) // false
console.log(Person.prototype.constructor.name) // Test

更優雅的寫法

function Person(name, age){
    this.name = name,
    this.age = age
    
}

Person.Prototype = {
    contructor: Person,
    // => 手動將 constructor 指向正確的構造函數 防止原型對象丟失
    type: 'human',
    sayName: function(){
        console.log("I am " + this.name);
    }
}
相關文章
相關標籤/搜索