这段js代码得节约你多少时间_Javascript教程-查字典教程网
这段js代码得节约你多少时间
这段js代码得节约你多少时间
发布时间:2016-12-30 来源:查字典编辑
摘要:1.应用案例:复制代码代码如下:varMouse=function(){//Look!nothat=this!this.position=[...

1.应用案例:

复制代码 代码如下:

var Mouse = function () {

// Look! no that = this!

this.position = [0, 0];

if (document.addEventListener) {

document.addEventListener('mousemove', ?); //this.move?

} else if (document.attachEvent) {

document.attachEvent("onmousemove", ?); //this.move?怎么放进去

}

};

Mouse.prototype.move = function (arg1,arg2,event) {

event = window.event || event;

var x = event.pageX || event.offsetX,

y = event.pageY || event.offsetY;

this.position = position = [x, y];

this.log(arg1,arg2);

};

Mouse.prototype.log = function (arg1, arg2) {

console.log(arg1+","+arg2);

console.log(this.position);

};

new Mouse();

上面你知道'?'号那里要干嘛了吗?我想给document的mousemove绑定我的move方法,但是遇到难题了,这样的话,Mouse.prototype.move

里的this就不会指向Mouse的对象,相信大家经常碰到这种问题.也许你早知道了怎么解决,但是有更快更简单的方法吗?答案是:

Function.prototype.bind()这个神奇的玩意,但是ie6 7 8都不支持,一般现代浏览器都支持了,我们接下来要做的就是模仿他,

这么好的方法当然要模仿它,怎么模仿见下面nothing的原创方法

复制代码 代码如下:

(function () {

var proxy = function (fn, target) {

var proxy = function () {

if (2 < arguments.length) { //存在被代理的函数有参数的时候

var privateArgs = Array.prototype.slice.call(arguments, 2);

//从第二个开始取出来,[this,绑定的对象,参数列表]

return function () {

var args = Array.prototype.slice.call(arguments);

-->这里的arguments与外面的不是同一个,这个是被代理的函数内部的arguments对象,

比如这里的move函数的 arguments[0]=[object Event]就是这个事件内部的e参数

Array.prototype.unshift.apply(args, privateArgs);

-->这里在加上传进来的参数,就实现了,和原生bind一样的参数形式

//->而且这里是把私有的参数放到前面的比如a=new Mouse();a.move(1,2);

//如果这个move方法没有参数,意思就是prototype.move=fn(){arguments} ,

//而我传进来了参数,参数的arguments.length=3,

//arguments[0]=1,arguments[1]=2,arguments[2]=[object event].

return fn.apply(target, args);

}

//这里之所以搞复杂了,是因为,在被代理的函数可以直接访问arguments,比如我不给被代理的函数传参数,而直接使用

//这样这个arguments就会包含与原生Function.prototype.bind的arguments一样的对象,

//这里代码深奥,是因为你没理解这里原生的bind里面的arguments是什么,知道了,就知道为什么绑定我自己的arguments

//做这么多,主要目的就是使你被代理的函数内部的arguments与function.prototype.bind里的arguments对象包含的东西一致

}

return function () {

return fn.apply(target, arguments);

}

}

return proxy.apply(null, arguments);

};

/*支持原生的使用原生的*/

Function.prototype.bind = Function.prototype.bind ||

function (target) { //这里的this指代要被代理的函数

if (1 < arguments.length) {

var args = Array.prototype.slice.call(arguments, 1); //取出参数列表

args.unshift(this, target); //这个args最终变成了[this,绑定的对象,参数列表]

return proxy.apply(null, args);

--如果直接proxy(args),麻烦来了,args成了proxy函数的一个参数,就会报错,

其实这里主要是分开任务处理,proxy只关心代理和参数是怎么传给proxy,如果被代理的没参数,直接;

return proxy(this, target)--> return fn.apply(target, arguments); 就是17楼的那个答案

-->估计大家会跟17楼犯一样的错误,这里之所以这么复杂的操作arguments对象,只是为了能保证传进proxy函数中,保证arguments对象不失效

}

return proxy(this, target);

};

})();

以上代码为什么我要一直return回来代理,因为这样你才能这样调用this.move.bind(this,1,2)()然后这里会立即执行函数!

有了以上代码,我们就可以轻松的实现了"?"号这里要写什么代码了,^_^,简单吧

复制代码 代码如下:

if (document.addEventListener) {

document.addEventListener('mousemove', this.move.bind(this,1,2));

} else if (document.attachEvent) {

document.attachEvent("onmousemove", this.move.bind(this,1,2));

}

是不是以后凡是碰到要添加事件,然后调用的方法的this又想指向其他对象,这样是不是很简单呢..

看到大家对以上代码有点难理解,来个简单点得

复制代码 代码如下:

var a = function () {

console.log(arguments[0]); //1

console.log(arguments[1]); //2

console.log(this.key1);

//这样绑定参数的话,我的参数列出来才能和原生的bind一样,就这么简单,

};

var b = {

key1: "value1"

};

a.bind(b, 1, 2)();

反驳17楼同学的代码错误,我想这是很多人会犯的错误,代码如下

复制代码 代码如下:

Function.prototype.bind = function (target) {

var self = this;

return function () {

return self.apply(target, arguments); //这里的arguments根本传不进来

}

}

var a = function () {

console.log(arguments.length); //这样bind的话,arguments参数失效

//arguments.length=0.

console.log(this.key1);

};

var b = {

key1: "value1"

};

a.bind(b, [1, 2], 3)(); //从这里可以看出,期望的arguments.length=2

//这也是我为什么苦口婆心的操作arguments参数

//我知道这里大部分人都会觉得对的,但是你错了,17楼的同学你还得在思考下

不带注释的源码,

复制代码 代码如下:

(function () {

var proxy = function (fn, target) {

var proxy = function () {

if (2 < arguments.length) {

var privateArgs = Array.prototype.slice.call(arguments, 2);

return function () {

var args = Array.prototype.slice.call(arguments);

Array.prototype.unshift.apply(args,privateArgs);

return fn.apply(target, args);

}

}

return function () {

return fn.apply(target, arguments);

}

}

return proxy.apply(null, arguments);

};

/*支持原生的使用原生的*/

Function.prototype.bind = Function.prototype.bind ||

function (target) {

if (1 < arguments.length) {

var args = Array.prototype.slice.call(arguments, 1);

args.unshift(this, target);

return proxy.apply(null, args);

}

return proxy(this, target);

};

})();

这篇文章是接着上篇文章讲得,我这个讲个详细的列子,如果没看就点

先看列子,本博客没时间去搞华丽的布局,只求朴实的代码,只为js代码爱好者使用

复制代码 代码如下:

var Mouse = function () {

if (document.addEventListener) {

document.addEventListener('mousemove', this.move.bind(this,1,2,[3,4]));

} else if (document.attachEvent) {

document.attachEvent("onmousemove", this.move.bind(this,1,2,[3,4]));

}

};

Mouse.prototype.move = function () {

console.log(arguments[arguments.length-1].clientX);

};

这里的arguments的输出结果很好的解释了上文代码,不懂得请结合新给出得列子配合理解.

复制代码 代码如下:

var privateArgs = Array.prototype.slice.call(arguments, 2);

//私有的参数,表示代理者的参数,这里代表1,2,[3,4]

return function () {

var args = Array.prototype.slice.call(arguments);

//这里的参数,代表被代理者的参数,这里如事件函数内部的e

Array.prototype.unshift.apply(args, privateArgs);

//这里是将两者的参数合并在一起,然后私有参数在前,目的也是为了和原生的参数顺序一致

return fn.apply(target, args);

//将合并后的参数这里包括1,2,[3,4] e传进去,并apply

}

好,到了这里,你会发现一个不错的js技巧,就是不用兼容处理e=window.event||e,直接使用arguments[arguments.length-1]就能兼容代表

所有浏览器的事件e对象,节省了不少的代码与思考的时间,

之所以写出这段代码,是希望大家对js代码有个真正的理解,知道js的真正魅力在哪里,如果了真看懂了此文,至少你知道了arguments到底是

怎么回事了,本博客破烂无比,只有朴实的代码,适合js代码爱好者学习.

其实真正的js魅力何止这点.有了以上的实例加上说明,相信你也应该了解得差不多了,不懂得多demo几下就知道了.

一个js爱好者,会时不时贴出一些较为新鲜的代码供大家学习,本博客的目的就是为了共同学习js代码的精髓.

相关阅读
推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
  • 大家都在看
  • 小编推荐
  • 猜你喜欢
  • 最新Javascript教程学习
    热门Javascript教程学习
    编程开发子分类