当前位置: 首页 > news >正文

域名备案后网站打不开重庆建设摩托官方网站

域名备案后网站打不开,重庆建设摩托官方网站,深圳设计公司 电话,免费个人二级域名网站昨天边参考es5-shim边自己实现Function.prototype.bind#xff0c;发现有不少以前忽视了的地方#xff0c;这里就作为一个小总结吧。 一、Function.prototype.bind的作用 其实它就是用来静态绑定函数执行上下文的this属性#xff0c;并且不随函数的调用方式而变化。 示例发现有不少以前忽视了的地方这里就作为一个小总结吧。 一、Function.prototype.bind的作用 其实它就是用来静态绑定函数执行上下文的this属性并且不随函数的调用方式而变化。 示例 test(Function.prototype.bind, function(){function orig(){return this.x;};var bound orig.bind({x: bind});equal(bound(), bind, invoke directly);equal(bound.call({x: call}), bind, invoke by call);equal(bound.apply({x: apply}), bind, invoke by apply); }); 二、浏览器支持 Function.prototype.bind是ES5的API所以坑爹的IE6/7/8均不支持所以才有了自己实现的需求。 三、实现 第一阶段 只要在百度搜Function.prototype.bind的实现一般都能搜到这段代码。 Function.prototype.bind Function.prototype.bind|| function(){var fn this, presetArgs [].slice.call(arguments); var context presetArgs.shift();return function(){return fn.apply(context, presetArgs.concat([].slice.call(arguments)));};}; 它能恰好的实现Function.prototype.bind的功能定义但通过看es5-shim源码就会发现这种方式忽略了一些细节。 第二阶段 被忽略的细节1函数的length属性用于表示函数的形参。 而第一阶段的实现方式调用bind所返回的函数的length属性只能为0而实际上应该为fn.length-presetArgs.length才对啊。所以es5-shim里面就通过bound.lengthMath.max(fn.length-presetArgs.length, 0)的方式重设length属性。被忽略的细节2函数的length属性值是不可重写的使用现代浏览器执行下面的代码验证吧 test(function.length is not writable, function(){function doStuff(){}ok(!Object.getOwnPropertyDescriptor(doStuff, length).writable, function.length is not writable);}); 因此es5-shim中的实现方式是无效的。既然不能修改length的属性值那么在初始化时赋值总可以吧也就是定义函数的形参个数于是我们可通过eval和new Function的方式动态定义函数来。 被忽略的细节3eval和new Function中代码的执行上下文的区别。 简单来说在函数体中调用eval其代码的执行上下文会指向当前函数的执行上下文而new Function或Function中代码的执行上下文将一直指向全局的执行上下文。 举个栗子 var x global;void function(){var x local;eval(console.log(x);); // 输出local(new Function(console.log(x);))(); // 输出global}(); 因此这里我们要是用eval来动态定义函数了。 具体实现 Function.prototype.bind Function.prototype.bind|| function(){var fn this, presetArgs [].slice.call(arguments); var context presetArgs.shift();var strOfThis fn.toString(); // 函数反序列化用于获取this的形参var fpsOfThis /^function[^()]*\((.*?)\)/i.exec(strOfThis)[1].trim().split(,);// 获取this的形参var lengthOfBound Math.max(fn.length - presetArgs.length, 0);var boundArgs lengthOfBound fpsOfThis.slice(presetArgs.length) || [];// 生成bound的形参eval(function bound( boundArgs.join(,) ){ return fn.apply(context, presetArgs.concat([].slice.call(arguments))); });return bound; }; 现在成功设置了函数的length属性了。不过还有些遗漏。 第三阶段 被忽视的细节4通过Function.prototype.bind生成的构造函数。我在日常工作中没这样用过不过这种情况确实需要考虑下面我们先了解原生的Function.prototype.bind生成的构造函数的行为吧请用现代化浏览器执行下面的代码test(ctor produced by native Function.prototype.bind, function(){  var Ctor function(x, y){    this.x x;    this.y y;   };   var scope {x: scopeX, y: scopeY};   var Bound Ctor.bind(scope);   var ins new Bound(insX, insY);   ok(ins.x insX ins.y insY scope.x scopeX scope.y scopeY, no presetArgs);   Bound Ctor.bind(scope, presetX);   ins new Bound(insY, insOther);   ok(ins.x presetX ins.y insY scope.x scopeX scope.y scopeY, with presetArgs); }); 行为如下 this属性不会被绑定预设实参有效 下面是具体实现 Function.prototype.bind Function.prototype.bind|| function(){var fn this, presetArgs [].slice.call(arguments); var context presetArgs.shift();var strOfThis fn.toString(); // 函数反序列化用于获取this的形参var fpsOfThis /^function[^()]*\((.*?)\)/i.exec(strOfThis)[1].trim().split(,);// 获取this的形参var lengthOfBound Math.max(fn.length - presetArgs.length, 0);var boundArgs lengthOfBound fpsOfThis.slice(presetArgs.length) || [];// 生成bound的形参eval(function bound( boundArgs.join(,) ){ if (this instanceof bound){ var self new fn(); fn.apply(self, presetArgs.concat([].slice.call(arguments))); return self; } return fn.apply(context, presetArgs.concat([].slice.call(arguments))); });return bound; }; 现在连构造函数作为使用方式都考虑到了应该算是功德圆满了吧NO上面的实现只是基础的实现而已并且隐藏一些bugs 潜伏的bugs列表 var self new fn()如果fn函数体存在实参为空则抛异常呢bound函数使用字符串拼接不利于修改和检查既不优雅又容易长虫。 第四阶段 针对第三阶段的问题最后得到下面的实现方式 if(!Function.prototype.bind){  var _bound function(){    if (this instanceof bound){    var ctor function(){};    ctor.prototype fn.prototype;    var self new ctor();    fn.apply(self, presetArgs.concat([].slice.call(arguments)));    return self;   }   return fn.apply(context, presetArgs.concat([].slice.call(arguments)));  }  , _boundStr _bound.toString();  Function.prototype.bind function(){    var fn this, presetArgs [].slice.call(arguments);    var context presetArgs.shift();    var strOfThis fn.toString(); // 函数反序列化用于获取this的形参    var fpsOfThis /^function[^()]((.?))/i.exec(strOfThis)[1].trim().split(,);// 获取this的形参    var lengthOfBound Math.max(fn.length - presetArgs.length, 0);    var boundArgs lengthOfBound fpsOfThis.slice(presetArgs.length) || [];// 生成bound的形参   // 通过函数反序列和字符串替换动态定义函数    var bound eval((0, _boundStr.replace(function(), function( boundArgs.join(,) )) ));    return bound;   }; 四、性能测试 // 分别用impl1,impl2,impl3,impl4代表上述四中实现方式 var start, end, orig function(){}; start (new Date()).getTime(); Function.prototype.bind impl1; for(var i 0, len 100000; i len;){  orig.bind({})(); } end (new Date()).getTime(); console.log((end-start)/1000); // 输出1.387秒 start (new Date()).getTime(); Function.prototype.bind impl2; for(var i 0, len 100000; i len;){   orig.bind({})(); } end (new Date()).getTime(); console.log((end-start)/1000); // 输出4.013秒 start (new Date()).getTime(); Function.prototype.bind impl3; for(var i 0, len 100000; i len;){   orig.bind({})(); } end (new Date()).getTime(); console.log((end-start)/1000); // 输出4.661秒 start (new Date()).getTime(); Function.prototype.bind impl4; for(var i 0, len 100000; i len;){   orig.bind({})(); } end (new Date()).getTime(); console.log((end-start)/1000); // 输出4.485秒 由此得知运行效率最快是第一阶段的实现而且证明通过eval动态定义函数确实耗费资源啊 当然我们可以通过空间换时间的方式Momoized技术来缓存bind的返回值来提高性能经测试当第四阶段的实现方式加入缓存后性能测试结果为1.456性能与第一阶段的实现相当接近了。 五、本文涉及的知识点 eval的用法new Function的用法除new操作符外的构造函数的用法JScriptIE6/7/8下诡异的命名函数表达式Momoized技术六、总结 在这之前从来没想过一个Function.prototype.bind的polyfill会涉及这么多知识点感谢es5-shim给的启发。 我知道还会有更优雅的实现方式欢迎大家分享出来一起面对javascript的痛苦与快乐 原创文章转载请注明来自^_^肥仔John[http://fsjohnhuang.cnblogs.com] 本文地址http://www.cnblogs.com/fsjohnhuang/p/3712965.html 本篇完  如果您觉得本文的内容有趣就扫一下吧捐赠互勉    转载于:https://www.cnblogs.com/fsjohnhuang/p/3712965.html
http://www.pierceye.com/news/250157/

相关文章:

  • 便宜网站制作wordpress函数手册
  • 适合在家做的网站工作做音乐网站要求
  • 在哪个网站做视频赚钱的建设彩票网站需要多少投资
  • 大连网站建设意动科技推荐做那个的电影网站
  • 博达 网站群建设wordpress打开乱码
  • 电商网站建设代理商定制网站开发介绍图
  • 网站系统问题解决措施上海网站建设系
  • c 做网站简单吗ui设计需要学什么软件
  • 网站建设app开发公司国内免备案空间
  • nas 支持做网站dedecms 做影网站
  • 网上商城网站模板广州建设技术职业学院
  • 养生网站模板下载山东网站建设哪家专业
  • 最新电子产品网站模板网站建设公司 腾佳
  • 跟公司产品做网站用什么程序做网站最好优化
  • 在线代理网页浏览网站山东省城乡住房建设厅网站
  • 网站建设需准备什么彩页模板图片
  • 怎么用网站源码建站网站换空间步骤
  • 酒店网站开发回扣商丘企业网站建设服务
  • 网站建设策划解决方案河北自助建站系统平台
  • 有没有做高仿手表的网站设计师的职责
  • struts2 做的网站seo公司怎样找客户
  • 帮别人做网站赚钱吗中山快速建站合作
  • 保靖网站建设做网站要运用到代码吗
  • 我用织梦5.7做个网站应该把淘宝客店铺链接放到哪frontpage可以制作网页吗
  • 潍坊优化网站排名在线网页设计培训机构
  • c做的网站ps做 网站标准尺寸
  • 老虎淘客系统可以做网站吗wordpress po mo
  • 网站的建设与维护那个网站做图片好
  • 昆山网站建设详细方案建设企业网站初始必备的六大功能
  • 做网站是前端还是后端网站规划 设计 制作 发布与管理过程