几种常见的创建对象的方式
一、工厂方式创建对象(不常用):
function student(name,age){
return{
name:name,
age:age,
nj:function(){
alert(this.name+"在读六年级");
//this指向当前对象
}
}
}
//调用被封装的对象即可
var stu = student('xxx',12);
stu.nj();
二、构造函数方式创建对象(不完善)
//代码规范:首字母大写
function Student(name,age){
this.name = name;
this.age = age;
this.nj = function(){
alert(this.name+"在读六年级");
}
}
//实例化对象
var stu = new Student('xxx',12);
stu.nj();
/*
调用new的时候:
1、先生成一个空对象
2、构造函数中的this指向当前对象
3、执行构造函数代码
*/
构造函数存在的问题
原因:构造函数都是一样的,但实际情况实例化对象的时候会实例化两次,此时不同的商品在内存中会生成同样的方法function,造成内存浪费。
三、构造函数+原型方法创建对象(常用)
//代码规范:首字母大写
function Student(name,age){
this.name = name;
this.age = age;
}
//每个构造函数都有一个prototype属性/对象,该属性所有的方法和属性都能被构造函数继承,可以将构造函数里的方法放入prototype中
Student.prototype.nj=function(){
alert(this.name+"在读六年级");
}
//如果实例对象没有对应的方法,会去构造函数的prototype内寻找
//如果实例对象和构造函数的prototype中都有对应的方法,会执行实例对象自己的方法
//实例对象的__proto__指向构造函数的prototype,即__proto__ == prototype
//可以通过下面这种方法修改底层代码
Student.__proto__.nj(){
//函数体;
}
//实例对象.hasOwnProperty('属性')可以判断是自有的还是继承的
Student.hasOwnProperty('name'); //true
Student.hasOwnProperty('age'); //true
Student.hasOwnProperty('nj'); //false
//可以通过constructor找到实例对象的构造函数,但是在某些情况下不太好用:stu.constructor
//某些情况指:重写实例对象的prototype会丢失constructor
//官方推荐使用a instanceof b(构造函数) 判断a是否提供b构造出来的:stu instanceof Student