array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 js prototype之诡异 - 爱码网

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

  • 特征一:“对象”是不可访问prototype属性,只有“类型”才可以访问portotype属性。
var x=0;
var y='1';
var z=[];
var w={};
var u=function(){}
// 以上对象类型中,仅有u是有protottype属性的,方法可以被看做是一种类型。
Array
Object
Function
Number
String
//以上是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

我们看一下调试器发现,

js prototype之诡异

js prototype之诡异

我们发现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

相关文章: