作为本博客的逻辑线,觉得还是从基础篇的来。先撸es5部分写几篇比较常用和非常有用的知识。
一、js的原型对象
原型对象是js实现继承的重要手段。
- 继承属性后,当查找某个元素时,js会沿着原型链不断的往上查找原型对象上的属性,如果有则返回,如果没有返回undefined
- 用案列说明:
function Proson(name, age) {}
Proson.prototype.summary = '我是最原始的说明';
var son = new Proson('张三','李四');
son.title = '我是son的自有属性';
son.prototype = {};
// 继承和查找
console.log(son.summary); // '我是最原始的说明' 属性被继承了
console.log(Proson.__proto__ === Function.prototype); // true
console.log(son.__proto__ === Proson.prototype); // true
- 上面列子可以说明一个事实:原型的继承还是通过原型链的方式进行的,而原型链就是通过属性的__proto__以及prototype进行链接的
- 子级的__proto__ 指向父级(构造函数)的 prototype对象,一级一级的进行查找
// 万物皆对象,从源头开始继承
console.log(Function.prototype.__proto__ === Object.prototype); // true
console.log(Proson.prototype.__proto__ === Object.prototype); // true
console.log(son.prototype.__proto__ === Object.prototype); // true
console.log(son.hasOwnProperty('title')); // true
- 从这几行打印可以看出,万物皆对象的本质意思,这也就是为什么这些函数可以使用 Object的一些方法的原因。
扩展小知识:
- 所以我们看某个对象是否有哪些方法,可以直接看继承的源头。
- 比如当我们想知道操作数组有哪些方法 可以输入 Array.prototype , 打印出的方法就是数组可以使用的全部方法
二、闭包(简单说明一下)
-
闭包一句话总结
带有私有的作用域(私有的上下文)的函数就是闭包 -
实现方法
- 在一个函数中嵌套了一个匿名函数,匿名函数可以访问这个函数里面的变量
列子:
- 在一个函数中嵌套了一个匿名函数,匿名函数可以访问这个函数里面的变量
function add(){
var name = '张三',age='18';
return function(value){
console.log(name + age + value)
}
}
var pople = add();
pople('周五去喝茶'); // 张三18周五去喝茶
-
闭包的作用:
- 实现拥共有变量
- 可以做缓存(存储结构)
- 可以实现封装,属性私有化
- 模块化开发,防止污染全局变量
- 私有变量查找优于全局查找速度
-
扩展小知识
- 说闭包一定会照成内存泄露的说法是错误,照成内存泄露是由浏览器内存清理的机制 和 程序代码的写法所决定的。
三、经典的运用 - JQ的共享原型设计
首先架构设计图:
jq源码比较重,然后也不要分析,简略的撸了一个图片懒加载的插件,咱们用案列说话:
下面是利用jq的核心共享原型思想编写的一个图片懒加载的插件
-
lazyloading.js
-
调用
核心点:1. 共享原型的设计,实现方法的直接调用,以及方法共享 Lazyloading.prototype.init.prototype = Lazyloading.prototype; 2. 链式的调用实现 方法的处理完成后 返回其实列对象 this ,可以进行后续的处理和链式调用 3. 闭包的处理,这个是插件一般的写法,这里就不赘述了。 闭包的形式,一般是用于保护变量,除了避免污染以外,全局查找效率也要比是有作用域查找慢得多
分析:
-
将方法都写在Lazyloading的原型上,通过init的方法进行初始化返回一个lazy的实列
-
利用共享原型的设计模式,将原型挂载到init的原型上
-
调用loading返回以后 继续返回原型实列,可以进行链式调用和处理
-
该插件知识点总结
- 原型共享机制
- 闭包形式
- 延续函数内部变量的周期,链式调用
- ; (function(){})() 写法 压缩js时避免别人没写,照成一些错误