本篇文章 主要接上篇文章 JS原型模式
1.扩展原型链
function Fn() {
this.x = 100;
this.y = 200;
this.getY = function() {
console.log(this.y);
}
}
//扩展公有属性
Fn.prototype = {
constructor: Fn, //--->一定要用constructor指向Fn 扩展一下 不然constructor就变成了Object 后续文章中会讲到
y:300,
getX: function() {
console.log(this.x);
},
getY: function() {
console.log(this.y);
}
}
var f = new Fn;
f.getX();//100
f.__proto__.getX();//undefined
//在原型模式中 this常用的有两种情况:
//在类中 this.xxx = xxx; this ---> 当前类的实例
//在某一个方法中 this --->看执行的时候 "."前面是谁 this就是谁
1)需要先确定this指向 ---> this是谁
2)把this替换成对应的代码
3)按照原型链查找的机制,一步步查找结果
f.__proto__.getX();//this 是f.__proto__
console.log(f.__proto__.x);//直接忽略了查找私有的 在公有中查询发现没有X --->输出undefined
Fn.prototype.getX();// --->undefined
console.log(Fn.prototype.x) //--->undefined
f.getY()
console.log(f.y) // ----> 200
f.__proto__.getY()
console.log(f.__proto__.y) // ---->输出300
复制代码
2.内置类扩展
- 在内置类的原型上扩展我们的方法
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.lenght - 1];//用最后一项覆盖这一项
this.length--;//删除最后一个元素
i--; //让i随之减1
continue;
}
//如果不重复 先把值放到对象中
obj[cur] = cur;
}
obj = null;
return this;//目的是为了实现链式写法
}
复制代码
3.链式写法
var ary = [];
ary.sort(function(a,b) {
return a - b;
}).reverse().pop();
复制代码
- 执行完数组的一个方法,可以紧接着执行下一个方法 ---上述代码就是链式写法
- 原理:ary(一个实例数组)为什么可以用sort方法? 因为sort是Array.prototype上的公有方法 而数组ary是Array这个类的一个实例,所以ary可以使用sort方法
- 数组才能使用我们Array原型上定义的属性和方法
- sort执行完成后的返回值是一个排序后的数组,可以继续执行reverse
- reverse执行完成的返回值是一个数组,可以继续执行pop
- pop执行完成的返回值是被删除的那个元素,不再是一个数组了,所以再执行push会报错
4.批量设置原型上的公有属性和方法
function Fn() {
this.x = 100;
}
Fn.prototype.getX = function() {
console.log(this.x);
}
var f1 = new Fn;
复制代码
- 1、起一个别名(jquery是这样做的)
function Fn() {
this.x = 100;
}
var pro = Fn.prototype;
pro.getX = function() {
}
pro.getY = function() {
}
pro.getZ = function() {
}
var f1 = new Fn;
//把原来原型指向的地址赋值给我们的pro 现在它们操作的是同一个内存空间
复制代码
- 2、重构原型对象的方式
function Fn() {
this.x = 100;
}
Fn.prototype = {
constructor:Fn,//(必须增加 才能使Fn.prototype.constructor指向Fn 否则指向Object 看示意图)
a: function() {
},
b: function() {
}
}
//{} -->开辟了一个新的堆内存
//Js中遇到{} 先开辟堆内存 然后存属性名和属性值
//自己新开辟一个堆内存,存储我们公有的属性和方法,把浏览器原来给Fn.prototype开辟的那个给替换掉
Fn.prototype = { constructor: Fn }//为什么要增加这一行
1)只有浏览器天生给Fn.prototype开辟的堆内存里边才有constructor,而我们自己开辟的这个堆内存没有这个属性,这样construcor指向的就不在是Fn,而是Object了 -->参考示意图
//console.log(f.constructor) 没做任何处理之前 输出Object
//为了和原来的保持一致,我们需要手动地增加constructor的指向
2)给内置类增加公有的属性
如给内置类增加数组去重的方法
Array.prototype = { //让内置类 指向新内存
constructor: Array,
unique: function() {
}
}
//理论上这种方式扩展内置类 内置类的原型指向类一块新内存 会把之前已经存在的原型上的属性和方法给替换掉
//但是用这种方式修改内置类 浏览器是给屏蔽掉的(所以不能用来修改内置类)
//不过我们可以一个个的修改内置类的方法,当我们通过下述方法在数组的原型上增加方法,如果方法名和原来内置的重复了,会把内置的修改掉
//所以在内置类的原型上增加方法,命名都需要加特殊的前缀 避免出现错误
Array.prototype.sort = function() {
console.log(this) //this ---> ary 指当前要操作的数组
}
复制代码
-
附示意图
-
动力: 这是我的学习笔记(来源于视频),您能从中得到收获和进步,是我分享的动力,帮助别人,自己也会更快乐
-
期望: 不喜勿喷,谢谢合作!如果涉及版权请及时联系我,马上删除!