博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js prototype之诡异
阅读量:6221 次
发布时间:2019-06-21

本文共 3501 字,大约阅读时间需要 11 分钟。

想必经常写js的人必然会经常性的用到prototype这个属性,我写这篇文章倒不是自己对prototype这个属性理解有多深刻,相反是因为自己理解肤浅,想通过写文章来加深理解。废话不多说。下面总结一下prototype的特征吧,也请高手砖头拍轻点。

  • 特征一:“对象”是不可访问prototype属性,只有“类型”才可以访问portotype属性。
var x=0;var y='1';var z=[];var w={};var u=function(){}// 以上对象类型中,仅有u是有protottype属性的,方法可以被看做是一种类型。ArrayObjectFunctionNumberString//以上是js的内置对象,它们是“类型”,都含有prototype属性

可以简单这么理解,可以通过new关键字的对象都包含prototype属性。

  • 特征二:prototype是保存实例方法的真正所在。

  valueof()、toString()、Array.push,call,apply等方法实际上都是保存在prototype属性的名下,只是我们实际使用这些方法时通过各自的实例来进行访问的。这样我们就可以通过prototype来重写这些方法了。

  1. 重写方法
    Number.prototype.toString = function () {     return "Number:" + this;}var x= 222;alert(x.toString());

     上边显示的结果是:"Number:222";

    Function.prototype.toString = function () {     return "function { native code }";}function aaa() {      return Math.max(1, 2);}alert(aaa.toString());
    //给当前的脚本库进行简单的加密处理
  2. 扩充方法
Array.prototype.max = function () {    for (var i = 0, max = this[0]; this[i]; i++) {         if (max < this[i])         max = this[i];    }    return max;}// 此方法仅限正数比较,字符串或其他对象无法比较
  • 特征三:prototype属性是特定类型对象的实例所共有的,也就是共享的一片内存区域,这片内存区域是在当前特定类型声明时创建的(如果特定类型是自定义函数,那么这片共享的内存区域就是在这个自定义函数声明时就开始创建)。对于特定类型的对象的prototype属性,他们在内存有且只保存着一份,只要你对prototype属性的修改,都会影响到所有的实例对象。
  • prototype的属性让js实现了晚绑定和极晚绑定

请看下面的代码:

1       var x={}; 2       var y={}; 3       console.log(x===y); 4       // 这里是false,相信大家都知道为什么,因为它们在内存中所处的地址不一样 5       6       var x={}; 7       var y=x; 8       console.log(x===y); 9       // 这里是true。10         11         function Nothing() { }12         Nothing.prototype.noArray = [];13         Nothing.prototype.noObject = {};14         var nothing1 = new Nothing();15         var nothing2 = new Nothing();16         console.log(nothing1.noArray === nothing2.noArray);17         console.log(nothing1.noObject === nothing2.noObject);18         // 此处,两个都为true,为什么呢,nothing1和nothing2公用了一片内存区域,它们都是指向空这个唯一的空对象和空数组的。

再举一个例证来说明:

function M() { }        M.prototype.val = 0;        var m1 = new M();        var m2 = new M();        console.log(m1.val);        console.log(m2.val);        // 这里会发现,两个值都是0        M.prototype.val = 2;        console.log(m1.val);        console.log(m2.val);        // 这里会发现,另个值都是2
  • 特征四:当我们尝试通过“对象.属性=value”来修改prototype中的属性时,其实并没有修改portotype属性,而是给当前创建了一同名的属性,prototype中的属性还是保留着。

还是拿上边的代码继续进行分析:

function Nothing() { }Nothing.prototype.noArray = [];Nothing.prototype.noObject = {};var nothing1 = new Nothing();var nothing2 = new Nothing();nothing1.noArray = null;console.log(nothing1.noArray === nothing2.noArray);console.log(nothing1.noObject === nothing2.noObject);// 这个时候发现,第一个是false,第二个是true

我们看一下调试器发现,

我们发现nothing1对象多了一个普通的属性。也就是说,当你尝试对prototype中的属性进行修改的时候,你其实并没有修改prototype中的属性,而是新追加了一个同名的“普通”属性。

仔细分析上述代码,就会得出下面这条结论了。

  • 特征五:当访问一个对象的某个属性的时候,优先访问的是“普通”属性,其次再访问prototype中的属性。

这样就能解释上面代码中第一个为什么是false了。同样,当删除对象属性时,优先删除的仍然是这个“普通属性”。

function Nothing() {}        Nothing.prototype.noArray = [];        Nothing.prototype.noObject = {};        var nothing1 = new Nothing();        var nothing2 = new Nothing();        nothing1.noArray = null;        console.log(nothing1.noArray === nothing2.noArray);        console.log(nothing1.noObject === nothing2.noObject);        // 第一个结果是false,第二个结果是true        delete nothing1.noArray;        console.log(nothing1.noArray === nothing2.noArray);        // 这时候nothing1.noArray是[],结果为true;        delete Nothing.prototype.noArray;        console.log(nothing1.noArray === nothing2.noArray);        // 这时候nothing1.noArray 和nothing2.noArray都为undefined,结果为true

转载于:https://www.cnblogs.com/dacuotecuo/p/3447639.html

你可能感兴趣的文章
路由器采购的前期准备
查看>>
100天设计100个网站来学编程-----我的畅想
查看>>
百度页面分享插件源代码
查看>>
Unity CullingMask
查看>>
利用https访问web站点
查看>>
d3数值转换与时间转换
查看>>
基础运维:详细系统文件目录说明
查看>>
易宝典文章——玩转Office 365中的Exchange Online服务 之六 了解Exchange Online对于邮箱使用的限制...
查看>>
Oracle Database常见存储用语Terms
查看>>
centos linux java安装
查看>>
【数据恢复】详解ORA-8103错误
查看>>
Windows Docker和Windows Nano Server来啦!
查看>>
oracle数据字典
查看>>
自动统计机器硬件信息插入数据库
查看>>
我的友情链接
查看>>
Apache日志分析 shell短语
查看>>
大型网站系统架构的演化
查看>>
Nginx 中last和break 及 permanent 和 redirect 的爱恨情仇
查看>>
致歉!《迟来的观后感》一文存在问题!
查看>>
mysql 安全
查看>>