var person1 = new Object(); person1.name = "bob"; person1.age = '22'; person1.job = 'frontend'; person1.sayName = function () { console.log(this.name); } person1.sayName(); // bob console.log(person1.age); // 22
var person2 = { name: 'bob', age: 22, job: 'frontend', sayName: function () { console.log(this.name); } } person2.sayName(); // bob
function createPerson(name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function () { console.log(this.name); }; return o; } var person1 = createPerson('bob', 22, 'frontend'); var person2 = createPerson('lynn', 22, 'doctor'); console.log(person1.name); // bob console.log(person2.name); // lynn
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function () { console.log(this.name); } /** * 與聲明函數在邏輯上是等價的 this.sayName = new Function("console.log(this.name)"); */ } var person1 = new Person('bob', 22, 'frontend'); var person2 = new Person('lynn', 22, 'doctor'); console.log(person1.name); // bob console.log(person2.name); // lynn
person1
和person2
分別保存着Person
的一個不一樣的實例。這兩個對象都有一個constructor
(構造函數)屬性,該屬性指向Person
frontend
console.log(person1.constructor === Person); // true console.log(person2.constructor === Person); // true
對象的constructor
屬性最初是用來標識對象類型的。可是,提到檢測對象類型,仍是instanceof
操做符要更可靠一些函數
console.log(person1 instanceof Object); // true console.log(person1 instanceof Person); // true console.log(person2 instanceof Object); // true console.log(person2 instanceof Person); // true
咱們在這個例子中建立的全部對象既是Object的實例,同時也是Person的實例,這一點經過instanceof操做符能夠獲得驗證,建立自定義的構造函數意味着未來能夠將它的實例標識爲一種特定的類型優化
// 看成構造函數使用 var person = new Person("bob", 22, "frontend"); person.sayName(); //"Nicholas" // 做爲普通函數調用 Person("lynn", 22, "doctor"); // 添加到window window.sayName(); //"Greg" // 在另外一個對象的做用域中調用 var o = new Object(); Person.call(o, "Kristen", 25, "Nurse"); o.sayName(); //"Kristen"
構造函數建立的對象方法,實際上執行屢次函數建立,會致使不一樣的做用域鏈和標識符解析,如:this
console.log(person1.sayName == person2.sayName); //false
建立兩個完成一樣任務的Function實例的確沒有必要;何況有this對象在,根本不用在執行代碼前就把函數綁定到特定對象上面。所以,大可像下面這樣,經過把函數定義轉移到構造函數外部來解決這個問題。prototype
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = sayName; } // 把sayName函數抽離出外部函數 function sayName() { console.log(this.name); }
存在問題:指針
function Person() { } Person.prototype.name = 'bob'; Person.prototype.age = 22; Person.prototype.job = 'frontend'; Person.prototype.sayName = function () { return this.name } var person1 = new Person(); console.log(person1.name); // bob console.log(person1.age); // 22 console.log(person1.job); // frontend console.log(person1.sayName()); // bob console.log(person1.sayName === person2.sayName); // true
咱們建立的每一個函數都有一個prototype(原型)屬性,這個屬性是一個指針,指向一個對象,而這個對象的用途是包含能夠由特定類型的全部實例共享的屬性和方法。若是按照字面意思來理解,那麼prototype就是經過調用構造函數而建立的那個對象實例的原型對象。使用原型對象的好處是可讓全部對象實例共享它所包含的屬性和方法。code
function Person(name, age, obj) { this.name = name; this.age = age; this.obj = obj; } Person.prototype = { constructor: Person, sayName: function () { console.log(this.name); } } var person1 = new Person('bob', 22, 'frontend'); var person2 = new Person('lynn', 22, 'doctor'); console.log(person1.name); // bob console.log(person2.name); // lynn console.log(person1.sayName === person2.sayName); // true
function Person(name, age, obj) { this.name = name; this.age = age; this.obj = obj; console.log('typeof this.sayName: ', typeof this.sayName); // 檢測sayName 是否是一個函數 // 實際上只在當前第一次時候沒有建立的時候在原型上添加sayName方法 if (typeof this.sayName != 'function') { Person.prototype.sayName = function () { return this.name; } } } var person1 = new Person('bob', 22, 'frontend'); var person2 = new Person('lynn', 22, 'doctor'); console.log(person1.name); // bob console.log(person2.name); // lynn console.log(person1.sayName()); // bob console.log(person2.sayName()); // lynn console.log(person1.sayName === person2.sayName); // true
function createPerson(name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function () { console.log(this.name); }; return o; } var person1 = new createPerson('bob', 22, 'frontend'); var person2 = new createPerson('lynn', 22, 'doctor'); console.log(person1.name); // bob console.log(person2.name); // lynn