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