//赋值给一个变量时候上下文会变化 var say = one.say; console.log(say('hoho')); // "hoho, undefined" //作为回调函数时也会发生变化 var yetother = { name:"yetother obj", method:function(callback){ return callback("Hola"); } } console.log(yetother.method(one.say)); //"Hola, "
神马意思呢,就是this.name是undefined,当one.say赋值给say是,实际上是say存储了指向函数对象的指针,say这个变量明显又是全局变量的一个属性,那么它运行的时候实际的上下文就变成了windows了,当然这个时候name就变成undefined了。回调这个也是一样,return 的是函数运行的结果。如果我们事先设置 windows.name="windows" 那么得到的结果就变成了 "hoho, windows" 和"Hola, windows" 了。
function bind(o, m){ return function(){ return m.apply(o, [].slice.call(arguments)); } } var othersay = bind(yetother, one.say); othersay("Hola"); //"Hola, yetother obj"
通过apply可以改变方法执行的上下文,那么我们构建一个函数来实现这样一个功能,通过使用方法调用实现上下文的改变,这样就不会出现上下文不是我们期望的上下文的情况了。
//这段是直接复制过来的。 // ECMAScript 5给Function.prototype添加了一个bind()方法,以便很容易使用apply()和call()。 if (typeof Function.prototype.bind === 'undefined') { Function.prototype.bind = function (thisArg) { var fn = this, slice = Array.prototype.slice, args = slice.call(arguments, 1); return function () { return fn.apply(thisArg, args.concat(slice.call(arguments))); }; }; } var twosay2 = one.say.bind(two); console.log(twosay2('Bonjour')); // "Bonjour, another object" var twosay3 = one.say.bind(two, 'Enchanté'); console.log(twosay3()); // "Enchanté, another object"
介绍完了,该说说自己的疑惑了,当复制属性方法遇到的被继承对象里边存在方法,如何单独复制出来呢,现在的是直接共用了,因为毕竟方法一般不会经常改动。求解答?
下面是转载过来的jQuery的extend方法,好像也没有特殊处理函数这块,继承完了两个函数也是共用的。
$.extend源码
jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false ; // Handle a deep copy situation //如果第一个参数是boolean类型 //修正参数,将第二个参数作为target if ( typeof target === "boolean" ) { deep = target; // skip the boolean and the target target = arguments[ i ] || {}; //i++是为了后续 i === length的判断 i++; } // Handle case when target is a string or something (possible in deep copy) //如果目标既不是对象也不是方法(例如给基本类型扩展属性方法和属性不会报错但是是无用的),修正target为 js对象 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } // extend jQuery itself if only one argument is passed //如果只有一个参数,修正对象为JQuery函数或JQuery对象 if ( i === length ) { target = this ; //修正target所在位置,后面的都是要添加给target的对象 i--; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop //如果target和copy是同一个对象,略过,防止自己的属性引用了本身对象导致的循环引用,以致GC无法回收 if ( target === copy ) { continue ; } // Recurse if we're merging plain objects or arrays //如果是deep为true,并且要添加给target的copy为对象获数组 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { if ( copyIsArray ) { copyIsArray = false ; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them //很巧妙 ,用一个递归,实现引用对象的深克隆,递归的返回条件是属性石基本类型,基本类型都是深克隆 target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { //浅克隆 target[ name ] = copy; } } } } // Return the modified object return target; };
以上这篇javascript 继承学习心得总结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章: