批量设置原型上的原型和方法
方法一
var pro = Fn.prototype; // 把原来原型指向的地址赋值给pro,现在他们操作的是同一个内存地址
pro.getX = function () {
console.log(this.x);
}
pro.getY = function () {
}
var f1 = new Fn();
方法二
重构原型对象的方式 -> 自己新开辟一个堆内存,存储公有属性和方法,把浏览器原来给Fn.prototype开辟的那个替换掉。
function Fn() {
this.x = 100;
}
Fn.prototype = {
// 手动增加constructor指向:
constructor: Fn,
a: function () {
},
b: function () {
},
c: function () {
}
}
var f = new Fn();
f.a();
f.b();
f.c();
- 只有浏览器天生给
Fn.prototype
开辟的堆内存里面才有constructor
,而我们自己开辟的这个堆内存没有这个属性, 这样constructor
指向就不再是Fn而是Object了
。
console.log(f.constructor); // -> 没做任何处理前,Object
// 为了和原来的保持一致,需要手动的增加constructor指向
- 用这种方式给内置类增加公有的属性
例如:给内置类Array增加一个数组去重的方法
Array.prototype.unique = function () {
}
Array.prototype = {
constructor: Array,
unqiue: function () {
// 这种方式不行
}
}
console.dir(Array.prototype);
这种方式会把之前存在于原型上的属性和方法替换掉,所以用这种方式修改内置类的话,浏览器是会将其屏蔽的。
但是我们可以一个个的修改内置类的方法,通过下述方式在数组的原型上增加方法,如果方法名和原来内置的重复了,会把内置的方法修改了。 -> 我们以后再内置类的原型上增加方法,命名都需要加特殊的前缀。
Array.prototype.sort = function () {
console.log(this); // this -> ary 当前要操作的数组
}
var ary = [1, 2, 3, 3, 1, 3, 4, 12];
ary.sort();
在原型模式中,this常用的有两种情况:
在类中,this.xxx = xxx;
this -> 当前类的实例。
某一个方法中的this -> 看执行的时候 "." 前面是谁,this就是谁。
- 需要先确定this的指向(即this是谁)。
- 把this替换成对应的代码。
- 按照原型链查找的机制,一步步的查找结果。
function Fn() {
this.x = 100;
this.y = 200;
this.getY = function () {
console.log(this.y);
}
}
Fn.prototype = {
constructor: Fn,
y: 300,
getX: function () {
console.log(this.x);
},
getY: function () {
console.log(this.y);
}
};
var f = new Fn();
f.getX(); // -> console.log(f.x) -> 100
f.__proto__.getX(); // -> this 是f.__protoo_ -> console.log(f.__proto__.x) -> undefined
Fn.prototype.getX(); // -> this 是Fn.prototype -> Fn.prototype.x -> undefined
f.getY(); // -> f.y -> 200
f.__proto__.getY(); // -> this是f.__proto__ -> f.__proto__.y -> 300
在内置类的原型上拓展一个方法,用于数组去重
Array.prototype.myUnique = function () {
// this -> ary
var obj = {};
for (var i = 0; i < this.length; i++) {
var cur = this[i];
if (obj[cur] === cur) {
this[i] = this[this.length - 1];
this.length--;
i--;
continue;
}
obj[cur] = cur;
}
obj = null;
return this; // 目的是为了实现链式写法
}
链式写法:执行完数组的一个方法,可以紧接着执行下一个方法。
原理:
ary为什么可以使用sort方法? -> 因为sort是Array.prototype
上的公有的方法,而数组是ary是Array的一个实例,所以ary可以使用sort方法 -> 只有数组才能使用Array原型上定义的属性和方法。
sort执行完成的返回值是一个排序后的"数组",所以可以继续执行reverse()。
reverse执行完成的返回值也是一个"数组",所以可以继续执行pop()。
pop()执行完成的返回值是被删除的最后一个元素,不是一个数组了,所以在执行数组相关操作会报错。
ary.sort(function (a, b) {
return a - b;
}).reverse().pop();
ary.myUnique(); // this -> ary
Array.prototype.myUnique(); // this -> Array.prototype
console.log(ary);