继承
1、原型链式的继承
这种继承有一个缺点就是它会继承过多没有用的属性,造成大量浪费.
2、借用构造函数
但是这种方式有两个缺点:
- 严格说,这种方式不属于继承,也访问不了原型的原型
- 每次构造一个对象都要走两个构造函数,效率很低
3、共享原型
Son.prototype = Foo.prototype;
但是这种方法也有弊端,那就是如果向单独改变子类原型上的属性时,就会两个一起都改变了。
4、圣杯模式
var inherit = (function () {
var f = function () {};
return function (C, P) {
F.prototype = P.prototype;
C.prototype = new F();
C.prototype.constructor = C;
C.prototype.uber = P;
}
} ());
this问题
1、预编译过程中 this -> window
2、全局作用域里面 this -> window
3、call/apply可以改变this指向
4、obj.func() 里面的this指向obj(谁调用的指向谁)
下面看一下例题:
var name = '222';
var a = {
name : '111',
say : function () {
console.log(this.name);
}
}
var fun = a.say;
fun(); // 输出222
a.say(); // 输出111
var b = {
name : '333',
say : function (fun) {
func();
}
}
b.say (a.say); //输出222
b.say = a.say;
b.say(); //输出333
call和apply:
apply和call基本没有区别,都是改变this指向的作用,唯一的区别是call后面的参数是一个一个传的,而apply后面的参数是放进一个数组里面然后传进去的。
对象的枚举
1、obj[‘name’]
这种对象查看的方式和数组类似,我们常用的obj.name在底层也会默认转成这种形式的,所以我推荐尽量采用这种方式查看对象的属性。
2、for-in
for-in循环会按照属性的顺序取出属性名然后赋给prop,obj[prop]则是相应的属性的值。
注意:如果写成obj.prop的形式,因为在系统底层会转成obj[‘prop’]的形式,但是我们并没有prop这个属性,所以会打印出来undefined。
3、hasOwnProperty
值得注意的是,在ES3和ES5的非严格模式中,for-in循环会把原型上的属性一起打印出来,所以就需要我们用hasOwnProperty来进行判断。
function Person () {
this.name : 'zhagsan';
}
Person.prototype = {
sex : 'male'
}
var oP = new Person();
for (var prop in oP) {
if (oP.hasOwnProperty(prop)) {
console.log(oP[prop]);
}
}
这样打印出来的数据就都是对象自身的属性了。
4、instanceof操作符
作用:判断前面对象的原型链上是否有后面构造对象
oP instanceof Person; // true
oP instanceof Object; // true
{} instanceof Object; // true
{} instanceof Person; // false