例子:https://github.com/wayaha/rotateChart
在ES5中,构造函数的使用可以说是很能体现面向对象的编程思想,有学过c的同学,可以很明显体会到面向过程和面向对象的区别,不多瞎扯,这次通过一个轮播图的插件来理解一下构造函数;
1、关于对象的创建方式
常见的创建对象方式有:字面量和通过new + 构造函数的方式;
字面量的方式相对灵活、简单;缺点也很明显,用一个需要造一个,不便于复用和属性的继承如下;
var person = { name: 'Picker', age: 18 , doSomething: function (){ console.log('I`m a developer, I can write code.'); } }
另外通过new的方式创建,常用的获取时间通过new Date();当然自己可以定义构造函数,如下,这样可以创建一群这样的人。
function Person (name, age) { this.name = name; this.age = age; }; Person.prototype.doSomething =function (){ console.log('I`m a developer, I can write code.'); };
var me = new Person('Picker',18)
用起来方便,但是在new的时候构造函数内部也做了一堆的操作:
var me={}; me.__proto__ = Person.prototype; Person.call(me); return me;
a、创建一个对象;
b、把空对象的原型对象指向构造函数的原型对象,此时空对象可以访问构造函数原型链上的方法和属性,这个很关键;
c、通过call方法改变构造函数的this指向,并执行构造函数,此时的对象拥有了构造函数的属性和方法;
d、返回对象me,即我们new出来的实例,构造函数默认有隐式返回,当构造函数有return时候,视情况而定,如果返回值是基础类型,构造函数忽略它的存在,继续返回默认值,如果是对象的形式,会返回该对象,代替生成的实例。
2、构造函数的创建
a、构造函数默认使用大驼峰命名,首字母大写;
b、构造函数的初始化,可以通过上面例子的方式,也可以是通过Object.defineProperty();
function Person( name){ Object.defineProperty(this, "name"{ get :function(){ return name; }, set:function (newName){ name =newName; }, enumerable :true, configurable:true //可配置 }); } var me=new Person('Picker');
c、在构造函数中使用原型对象;
doSomething方法就是原型对象的方法;如果需要挂载到原型上的对象更多,可以使用字面量的方式,如:
Person.prototype ={ sayName :function(){ console.log(this.name); },
doSomething =function (){
console.log('I`m a developer, I can write code.');
};
}
使用字面量形式改写了原型对象改变了构造函数的属性,因此他指向Object而不是Person。这是因为原型对象具有一个constructor属性。当一个函数被创建时,它的prototype属性也被创建,且该原型对象的constructor属性指向该构造函数。当使用对象字面量形式改写原型对象时,其constructor属性将被置为对象Object.为了避免这一点,需要在改写原型对象的时候手动重置constructor,如下:
Person.prototype ={ constructor = Person, sayName :function(){ console.log(this.name); }, doSomething =function (){ console.log('I`m a developer, I can write code.'); }; }
d、另外,在构造函数中this指向问题
箭头函数是不能用来创建构造函数的;
构造函数中定义方法使用 function() {},不要使用箭头函数,箭头函数中的this会指向window,而不是构造函数或者实例;
构造函数中关于事件绑定的函数,需要改变函数的this指向构造函数或者实例,如果需要的话;