JS原型模式扩展

本篇文章 主要接上篇文章 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 指当前要操作的数组
}
复制代码
  • 附示意图

  • 动力: 这是我的学习笔记(来源于视频),您能从中得到收获和进步,是我分享的动力,帮助别人,自己也会更快乐

  • 期望: 不喜勿喷,谢谢合作!如果涉及版权请及时联系我,马上删除!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值