我们可以通过创建自定义的构造函数,从而定义自定义对象类型的属性和方法。
例如:
function Person(name.age,sex){ this.name = name; this.age = age; this.sex = sex; this.sayName = function(){ alert(this.name); } } 然后我们实例一个Person var person1 = new Person("john",18,"男"); var person1 = new Person("Rose",17,"女");
我们注意到,Person()中的代码:
没有显式地创建对象;
直接将属性和方法赋给了this 对象;
没有return 语句。
此外,还应该注意到函数名Person 使用的是大写字母P。按照惯例,构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。这个做法借鉴自其他OO 语言,主要是为了区别于ECMAScript 中的其他函数;因为构造函数本身也是函数,只不过可以用来创建对象而已。
要创建Person 的新实例,必须使用new 操作符。以这种方式调用构造函数实际上会经历以下4个步骤:
(1) 创建一个新对象;
(2) 将构造函数的作用域赋给新对象(因此this 就指向了这个新对象);
(3) 执行构造函数中的代码(为这个新对象添加属性);
(4) 返回新对象。
person1 和person2 分别保存着Person 的一个不同的实例。这两个对象都有一个constructor(构造函数)属性,该属性指向Person,如下所示。
alert(person1.constructor == Person); //true alert(person2.constructor == Person); //true
对象的constructor 属性最初是用来标识对象类型的。但是,提到检测对象类型,还是instanceof 操作符要更可靠一些。我们在这个例子中创建的所有对象既是Object 的实例,同时也是Person的实例,这一点通过instanceof 操作符可以得到验证。
alert(person1 instanceof Object); //true alert(person1 instanceof Person); //true alert(person2 instanceof Object); //true alert(person2 instanceof Person); //true
// 当作构造函数使用 var person = new Person("Nicholas", 29, "man"); person.sayName(); //"Nicholas" // 作为普通函数调用 Person("Greg", 27, "women"); // 添加到window window.sayName(); //"Greg" // 在另一个对象的作用域中调用 var o = new Object(); Person.call(o, "Kristen", 25, "Nurse"); o.sayName(); //"Kristen"
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = new Function("alert(this.name)"); // 与声明函数在逻辑上是等价的 }
alert(person1.sayName == person2.sayName); //false
function Person(name, age, sex){ this.name = name; this.age = age; this.sex= sex; this.sayName = sayName; } function sayName(){ alert(this.name); } var person1 = new Person("Nicholas", 29, "man"); var person2 = new Person("Greg", 27, "woman");