标签:des style blog http io color ar os 使用
一、extend:扩展对象的属性
1 var Util = { 2 extend: function (dest) { 3 var i, j, len, src; 4 for (j = 1, len = arguments.length; j < len; j++) { 5 src = arguments[j]; 6 for (i in src) { 7 dest[i] = src[i]; 8 } 9 } 10 return dest; 11 } 12 }
可以,看出extend方法里有2个for循环,具体的作用一看便知:第一个是拿到所有参数,第二个是遍历当前参数对象的属性并作为目标对象的属性。代码j = 1还是很明智的,减少只传一个对象时的循环。对extend如何使用举个例子:
1 var A = { 2 name: ‘山.鬼瑶‘, 3 funA: function(){ 4 console.log(‘A‘); 5 }, 6 funB: function(){ 7 console.log(‘B‘); 8 } 9 }; 10 var B = { 11 job: ‘web研发-js‘, 12 show: function(){ 13 console.log(‘前端工程浩大,孜孜不倦,孜孜不倦‘); 14 } 15 }; 16 //将A、B属性扩展到C 17 var C = Util.extend(A, B); 18 19 C.funA(); //A 20 C.funB(); //B 21 console.log(C.name); //山.鬼瑶 22 console.log(C.job); //web研发-js 23 C.show(); //前端工程浩大,孜孜不倦,孜孜不倦
结果如上图所示,那么这个C扩展了A、B的属性作为自己的属性,因此,extend函数的作用有:
(1)扩展一个对象的属性和方法;
(2)在grunt压缩中,为了防止prototype被压缩丢失(因为带“”的属性,可能不会被当做引用,grunt压缩后,会存在丢失),可以采用extend(A.prototype)的形式引用一遍。
二、create:创建一个对象并赋原型,原型继承
1 create: Object.create || (function () { 2 function F() {} 3 return function (proto) { 4 F.prototype = proto; 5 return new F(); 6 }; 7 })()
create方法用了2个函数,一个是Object.create ( 即Object.create(prototype, descriptors)、另一个是及时函数(立即执行)。Object.create已经很明显了,是初始化一个带原型属性的对象。及时函数中,构建了一个F的对象,然后将外部传递的对象,作为F的原型。这个典型的应用场景就是原型继承,如下:
1 var B = {}; 2 B.prototype ={ 3 test: function(){ 4 console.log(‘b protoype: test‘); 5 } 6 }; 7 8 var C = Util.create(B.prototype); 9 C.test(); //b protoype: test
三、bind:将指定的对象及上下文绑定到函数
首先,来看一下原生的bind:
1 // 定义原始的函数 2 var checkNumericRange = function (value) { 3 console.log(this); 4 if (typeof value !== ‘number‘) 5 return false; 6 else 7 return value >= this.minimum && value <= this.maximum; 8 } 9 10 checkNumericRange(25); //此时,checkNumericRange是全局对象window的实例 11 12 console.log(‘---------------调皮的分隔符------------------‘); 13 // 取值范围对象 14 var range = { minimum: 10, maximum: 20 }; 15 // 绑定checkNumericRange对象 16 // this指向的是range 17 var boundCheckNumericRange = checkNumericRange.bind(range); 18 19 // 用心新的函数检测12是否在数组范围内 20 var result = boundCheckNumericRange (12); 21 console.log(result); //true 22 console.log(boundCheckNumericRange(24)); //false
可以,看出bind可以改变函数内部的this指向,同时绑定函数。再来看一个例子,对bind理解就会更加深入了:
1 //重新创建一个对象,包含checkNumericRange方法 2 var originalObject = { 3 minimum: 50, 4 maximum: 100, 5 checkNumericRange: function (value) { 6 console.log(this); 7 if (typeof value !== ‘number‘) 8 return false; 9 else 10 return value >= this.minimum && value <= this.maximum; 11 } 12 } 13 14 // 检测10是否在范围内,这次的this指向的是字面量originalObject 15 var result = originalObject.checkNumericRange(20); 16 console.log(result + " "); //false 17 18 console.log(‘-------------调皮的分隔线------------------‘); 19 20 var range = { 21 minimum: 10, 22 maximum: 20 23 }; 24 // 构建一个新版的checkNumericRange 25 //这次的this指向的是range 26 var boundObjectWithRange = originalObject.checkNumericRange.bind(range); 27 28 // 检测10是否在范围内 29 var result = boundObjectWithRange(10); 30 console.log(result); //true
再来看一下绑定函数作为3、4参数传递的例子:
1 var displayArgs = function (val1, val2, val3, val4) { 2 console.log(val1 + " " + val2 + " " + val3 + " " + val4); 3 } 4 5 var emptyObject = {}; 6 7 //将12 和 a作为第一个和第二个参数传入 8 var displayArgs2 = displayArgs.bind(emptyObject, 12, "a"); 9 10 //将b c作为第三第四个参数传入 11 displayArgs2("b", "c"); //12 a b c
那么问题就来了,如何写出像蓝翔挖掘机一样的bind呢?代码如下:
1 bind: function (fn, obj) { 2 var slice = Array.prototype.slice; 3 //ES5给function增加了bind方法,没有的话就模拟bind方法 4 if (fn.bind) { 5 //slice.call(arguments, 1):拿到obj之后的参数作为数组 6 return fn.bind.apply(fn, slice.call(arguments, 1)); 7 } 8 9 var args = slice.call(arguments, 2); 10 return function () { 11 return fn.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments); 12 }; 13 }
调用:
var test = Util.bind(function(){ console.log(this.a + this.b); }, {a: 3, b:4}); test(); //7
leaflet开源地图库源码研读(五)——extend、Object.create、fn.bind分析(Util.js文件)
标签:des style blog http io color ar os 使用
原文地址:http://www.cnblogs.com/vczero/p/leaflet_5.html