Comments (32)
个人优化后的版本
Function.prototype.applyOne = function(context){
context.fn = this;
eval('context.fn('+(arguments[1]||[]).toString()+')');
delete context.fn;
}
(我也算参与过1.2k的大项目了么
from blog.
原生的apply 支持 参数是对象 如果用eval模拟要完全用字符串拼接 不然会有问题
@jawil
应该吧
var fnStr = 'context[fn]('
for (var i = 0; i < args.length; i++) {
//得到"context.fn(arg1,arg2,arg3...)"这个字符串在,最后用eval执行
fnStr += i == args.length - 1 ? args[i] : args[i] + ','
}
fnStr += ')'
改为
var fnStr = 'context[fn]('
for (var i = 0; i < args.length; i++) {
//得到"context.fn(arg1,arg2,arg3...)"这个字符串在,最后用eval执行
fnStr += i == args.length - 1 ? 'args[' + i + ']' : 'args[' + i + ']' + ','
}
fnStr += ')'
from blog.
sayHello.applyFive(obj,['hello']是有问题的,eval解析时hello未定义,用toString也是不行的
from blog.
当初考虑的情况确实只是最简单的字符串,因为只是提供一种实现的思维,感谢指正 @zyg-github
from blog.
好巧,我们今天的文章同时讲到了call和apply的模拟实现
from blog.
不过现在的bind的模拟实现其实是有个小问题的,我专门私信了颜海镜求证了这个问题。
from blog.
length问题?@mqyqingfeng 同事朋友去51信用卡遇到这个面试题,我上周写了一半,今天看见你发了,我也赶紧写完,发现思路都差不多,我主要是先实现apply引出的。。。😄
from blog.
并不是哦,如果你比较MDN英文版和中文版的实现,就会发现这个问题。先卖个关子,明天发布的文章讲解bind的模拟实现就会讲到这个问题。(๑•̀ㅂ•́)و✧
from blog.
恩恩,我会关注呢,反正你一发就会有邮件推送😄
from blog.
仔细看了你的这篇文章,嗯,觉得……哈哈,建议楼主在整理资料的过程中慢慢找到自己的思路去表达,否则按照参考文章的思路去写,容易显得似曾相识。我自己也有这样的问题,与楼主共勉。
from blog.
看了有些文章,最后那个三元判断是这种的
this instanceof F ? this : context || window
有点迷糊
from blog.
在非严格模式下,走后面逻辑的话此时的this就是指向window,其实是一个东西。。。@xumeiyan
from blog.
Function.prototype.applyTwo = function(context) {
var argsPar=arguments[1]
context.fn = this;
var args = [];
for (var i = 0, len = argsPar.length; i < len; i++) {
args.push('argsPar[' + i + ']');
}
var str='context.fn(' + args + ')'
eval('context.fn(' + args + ')');
delete context.fn; //执行完毕之后删除这个属性
}
//测试一下
var jawil = {
name: "jawil",
sayHello: function(age) {
console.log(this.name, age);
}
};
var lulin = {
name: "lulin",
};
jawil.sayHello.applyTwo(lulin, ['hello']) //lulin 24
改成这样就ok了@Mrzhangyasheng
from blog.
都是基础啊,理解原理了自然就可以写出来了
from blog.
大多数(可能是所有)原生对象上的方法的prototype
为undefined
, 比如 Array.prototype.push.prototype === undefined
. 于是这样使用会报错:
var obj = {0: 'a', 1: 'b', length: 2}
// 原生bind
var each1 = Array.prototype.forEach.bind(obj, function(item) {
console.log(item)
})
var each2 = Array.prototype.forEach.bindOne(obj, function (item) {
console.log(item)
})
each1() // a b
each2() // Uncaught TypeError: Function has non-object prototype 'undefined' in instanceof check
个人做了这样的优化
var F = function () {};
F.prototype = this.prototype || Object.create(null);
from blog.
感谢补充优化,不过Object.create(null)好像是ES5的方法,用在这里hack好像不太合适,不过也没事,其实Object.create的也很好模拟实现 @leat14536
from blog.
请教一个问题,您实现apply的第三步中通过以下方式来实现当this
为空时指向window
:
var context = context || window
可是,当this
为空时,apply
应该是不能传递参数的吧?
applyFive([1,2])
这样是不行的
这块我有点不明白,请您指教一下。。
from blog.
@axuebin 处理的是这种情况 fn.apply(null, [1, 2])
from blog.
感谢@mqyqingfeng 百忙之中作出回答😂
from blog.
明白了。。我之前有一个地方写错了,导致apply()
即没this又没参数时出错了。。谢谢~
from blog.
不错不错,厉害,不过applyFive没传参的直接执行的时候没有执行delete context[fn]。
if (args == void 0) { //没有传入参数直接执行
var returnValue = context[fn]();
delete context[fn];
return returnValue;
}
from blog.
博主真厉害,按照您的步骤进行到如图标红的一步,发现args
是上图中的第一行代码(是个对象),但是却有个length属性,能不能解释一下为什么啊?
from blog.
@gaopeng0108 arguments 对象是一个类数组对象,就是会有一个 length 属性,你在浏览器中可以看到这个属性,可以参考这篇文章 mqyqingfeng/Blog#14
from blog.
飚一句zanghua,前端感觉真TM任重而道远
from blog.
apply在没有传参的时候直接返回了contextfn,但是好像没有把context的fn删除呢
from blog.
厉害!
from blog.
莫非你就是1024康先生,麻烦送一码。1024。
from blog.
哈哈哈哈哈,我前几天在某个群里也看到这条题目,我今天想了半天,偶然意识到可以这样:
// ...省略
obj.fn = fn
let result = obj.fn(...arr)
delete obj.fn
return result
我写完觉得这样是不是不好,然后我就网上搜,发现你大致也是这样做的,开心~
from blog.
from blog.
from blog.
bind方法传递给调用函数的参数可以逐个列出,也可以写在数组中。
这句感觉不太对吧,需要逐个列出,不可以放在数组中
from blog.
from blog.
Related Issues (20)
- test
- question
- 学习了!
- 安利一下自己为 GitHub 开发的首个 Chrome 插件—GayHub😂 HOT 51
- CSS 黑魔法小技巧,让你少写不必要的JS,代码更优雅 HOT 47
- JavaScript 优雅的实现方式包含你可能不知道的知识点 HOT 44
- blog搬家了?请放出地址呦 HOT 2
- 一行代码实现一个简单的模板字符串替换 HOT 17
- 哥们你域名过期了 http://qdxmq.com/ HOT 1
- add方法里的数组有没有必要抽出一个config.js文件 HOT 1
- 3 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #------------------------------------------------- # # Project created by QtCreator 2018-10-25T08:32:36 # #------------------------------------------------- QT += core gui QT += serialport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = COMTOOLV2 TEMPLATE = app RC_FILE =main.rc # The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLS HOT 2
- a == 1 && a == 2 && a == 3 输出true方法
- 前端小蜜圈链接跳转到了菠菜站了 HOT 2
- PM2部署网站的一个诡异缓存问题
- echo 127.0.0.1
- vue项目 HOT 1
- m
- 停更了?
- 三次握手与四次挥手
- 有人继续维护吗? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from blog.