💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## javascript 三座大山 这个标题其实我自己总结的,目前网络上没有相关的说法。意思就是javascript中比较重要难懂的三点知识。熟练掌握了这三点,你的javascript的基本功才算是过关。否则,你去BAT这种公司去面试前端,估计是过不了关。 - **原型和原型链** - **上下文环境和作用域** - **单线程和异步** 以上这『三座大山』我希望能找机会跟大家单独分享,此处只讲第一个的一部分,即讲到你能看懂后面zepto的设计,就够了。 <br> ## `Array.prototype` 先记住一句话——**每一个函数,都有一个`prototype`属性**——每一个函数,无论是你自定义的,还是系统内置的。不信可以试试。 ```js var fn = function() {} console.log( fn.prototype ); ``` 这里打印出来的`fn.prototype`是一个对象,只有一个`constructor`属性,指向该函数自身,即`fn.prototype.constructor === fn`。 ![](https://box.kancloud.cn/2016-07-04_577a764cd4521.png) 以上是自定义的函数,数组构造函数`Array`也是一个函数,只不过是浏览器内置的函数,它也得符合以上那句话。 ```js console.log( typeof Array ); // 'function' console.log( Array.prototype ); ``` 这里打印出来的`Array.prototype`也是一个对象,也有一个`constructor`属性,指向该函数自身。只不过还内置了其他的属性——废话,内置的对象毛用没有还内置个卵劲啊。 ![](https://box.kancloud.cn/2016-07-04_577a764d259d6.png) <br> ## `[].__proto__` 然后,再记住一句话——**所有通过函数`new`出来的东西,这个东西都有一个`__proto__`指向这个函数的`prototype`**,这里我们给他们分别取一个中文名字: - `prototype` (显示)原型 - `__proto__` 隐式原型 ```js var arr = []; // 等价于 var arr = new Array() arr.__proto__ === Array.prototype; // true ``` ![](https://box.kancloud.cn/2016-07-04_577a764d3a167.png) 然后,再记住一句话——**当你想要使用一个对象(或者一个数组)的某个功能时:如果该对象本身具有这个功能,则直接使用;如果该对象本身没有这个功能,则去`__proto__`中找** ```js var obj = { fn1: function () { console.log('fn1'); } }; obj.fn1(); // 'fn1' obj.toString(); // '[object Object]' (在 obj.__proto__ 中找到) ``` 数组也一样 ```js var arr = []; arr.push(1); // 在 arr.__proto__ 中找到了 push 方法 ``` 这就是为何数组会有`concat`、`push`等方法,顺藤摸瓜最终摸到了`Array.prototype`中来了。 因此,下列代码是成立的 ```js [].concat === Array.prototype.concat; [].push === Array.prototype.push; [].map === Array.prototype.map; ``` <br> ## `__proto__`是可修改的 上一节我们说过,`__proto__`就是一个基本的js对象,根据js无底线的语法规则,它是完全可以被修改或者重写的。这里不妨就再多唠叨两句。 ![](https://box.kancloud.cn/2016-07-04_577a764d558af.png) 修改`__proto__`的例子。修改了之后,`arr`不仅有内置的`concat`、`push`等功能,还多了一个`addClass`功能。 ```js var arr = [1,2,3]; arr.__proto__.addClass = function () { console.log(123); } arr.push(4); arr.addClass(); // 123 ``` 完全重写 `__proto__` 的例子,上一节讲过。还是注意,重写`__proto__`之后,`arr`可就失去了`concat`、`push`等亲人了,只有一个`addClass`功能了。 ```js var arr = [1,2,3]; arr.__proto__ = { addClass: function () { console.log(123); } }; arr.addClass(); // 123 ``` <br> ## 总结 第一,上文中有三句话要记住并且理解; 第二,有了这些基础知识,再去扒zepto的皮就轻而易举了; 第三,关于js的原型和原型链的知识,真的还有很多话没有说; <br>