JS new,構造函數模式和原型模式的知識總結
1,每個實例化的對象都有constructor屬性,指向實例的構造函數。
2,每個函數(Function)都有prototype屬性,這個屬性是一個指針,指向一個對象。
1,構造函數模式
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
console.log(this.name);
};
}
var person1 = new Person('huhu',23,'sd');
var person2 = new Person('you', 25, 'sf');
console.log(person1.constructor); // Person
console.log(Person.prototype.constructor); // Person
console.log(Person.prototype.constructor === person1.constructor); // true
console.log(person1.__proto__); // constructor 因爲原型prototype上沒有定義屬性,故只有默認的constructor屬性
console.log(person1.__proto__ === Person.prototype); // true
由上面的說明可知:
1,person1實例有constructor屬性指向Person.
console.log(person1.constructor); // Person
2,每個實例(person1,person2)都有__proto__屬性指向構造函數的原型。
構造函數存在的問題:不同的實例對象,不能公用構造函數中的方法,導致佔用內存。
(person1和person2是不同的實例,他們在內存都是單獨的引用,所以調用了不同的方法sayName,
但是,像這種方法可以爲每一個實例共享的,沒必要浪費內存。)
2,new 操作符做了什麼
(1)創建一個對象
(2)將構造函數的作用域賦給新對象(因此this就指向了這個新對象)
(3)執行構造函數中的代碼 (爲這個新對象添加屬性)
(4)返回新對象
var obj = {};
obj.__proto__ = Person.prototype;
Person.call(obj);
3,原型模式
function Person() {
}
Person.prototype.name = 'huhu';
Person.prototype.age = 23;
Person.prototype.job = 'sf';
Person.prototype.getName = function () {
console.log(this.name);
}
var person1 = new Person();
var person2 = new Person();
console.log(person1);
console.log(person1.name === person2.name); //true
console.log(person1 == person2); // false
console.log(person1.__proto__ === person2.__proto__); // true
console.log(person1.__proto__ === Person.prototype); // true
原型模式的問題:1,不能傳參數。2,對引用類型的值,會被改變。
4,組合使用構造函數模式和原型模式
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.friends = ['hu','you']; // 引用類型
}
Person.prototype = {
constructor: Person, // 因爲重寫了對象,不然就指向了Object
sayName: function () {
console.log(this.name);
}
};
var person1 = new Person('huhu',23,'sd');
var person2 = new Person('you', 25, 'sf');
person1.friends.push('van');