js构造函数+原型
注:普通对象与函数对象
var o1 = {}; var o2 =new Object(); var o3 = new f1(); function f1(){}; var f2 = function(){}; var f3 = new Function('str','console.log(str)'); console.log(typeof Object); //function console.log(typeof Function); //function console.log(typeof f1); //function console.log(typeof f2); //function console.log(typeof f3); //function console.log(typeof o1); //object console.log(typeof o2); //object console.log(typeof o3); //object
在上面的例子中 o1 o2 o3 为普通对象,f1 f2 f3 为函数对象。每个函数对象自带一个prototype属性,这个属性指向函数的原型对象。
1、构造函数法
/** * Person类:定义一个人,有name属性和getName方法 */ <script> function Person(name){ this.name = name; this.getName = function(){ return this.name; } } //我们在这里实例化几个对象 var p1 = new Person("tom"); var p2 = new Person("jerry"); console.log(p1 instanceof Person);//true console.log(p2 instanceof Person);//true
console.log(p1.name); //tom
console.log(p2.getName());//jerry
</script>
这里,instanceof
用来检测对象p1
是否属于Person
类。instanceof
操作符左边是待检测类的对象,右边是定义类的构造函数。
优点是:我们可以根据参数来构造不同的对象实例 ,缺点是 : 每次构造实例对象时都会生成getName
方法,造成了内存的浪费 。
我们可以用一个外部函数来代替类方法,达到了每个对象共享同一个方法。
//外部函数 <script> function getName() { return this.name; } function Person(name){ this.name = name; this.getName = getName;// } </script>
2、原型方式
<script> function Person(){}; Person.prototype.name = "tom";//类的属性都放在prototype上 Person.prototype.getName = function(){ return " I'm " + this.name; } var p1 = new Person(); var p2 = new Person(); console.log(p1.name);//tom console.log(p2.getName());//I'm tom </script>
原型方式
的缺点就是不能通过参数来构造对象实例 (一般每个对象的属性是不相同的) ,优点是所有对象实例都共享getName
方法(相对于构造函数方式),没有造成内存浪费 。
3、构造函数+原型方式
取前面两种的优点:
a、用构造函数来定义类属性(字段)。
b、用原型方式来定义类的方法。
<script> function Person(name){ this.name = name; Person.prototype.getName = function(){ return this.name; } } var p1 = new Person('tom'); console.log(p1.getName());//tom </script>
4、Object.create()方法
用这个方法,"类"
就是一个对象,而不是函数。
var Person = { name : "tom", age : 21, run: function(){ alert("I like running"); } } var p1 = Object.create(Person); alert(p1.age);//21 p1.run();//I like running
用Object.create()
生成实例,不需要用到new。这种方法比"构造函数法
"简单,但是不能实现私有属性和私有方法,实例对象之间也不能共享数据,对"类"的模拟不够全面。