Comments (28)
补充一个使用 apply
的例子。
比如求一个数组的最大值,使用 Math.max
函数,但是这个函数入参不支持数组,只能是将多个参数逐个传入,用逗号分隔。
let max = Math.max(1, 4, 8, 9, 0)
有了 apply
,就可以这么调用:
let arr = [1, 4, 8, 9, 0];
let max = Math.max.apply(null, arr);
from blog.
2.借用别的对象的方法
Person1.call(this) 的作用就是使用 Person1 对象代替 this 对象
我的理解是 Person1 的 this 变成 Person2的this,并执行一遍Person1函数
Person2就多了一个name属性
from blog.
ES6里面的call还能用解构来传参
const f = function (a, b, c) { console.log(a, b, c) } const arr = [1, 2, 3] f.call(null, ...arr)
from blog.
if (!Function.prototype.bind) { Function.prototype.bind = function () { var self = this, // 保存原函数 context = [].shift.call(arguments), // 保存需要绑定的this上下文 args = [].slice.call(arguments); // 剩余的参数转为数组 return function () { // 返回一个新函数 self.apply(context,[].concat.call(args, [].slice.call(arguments))); } } }以上返回的函数体中的 self.apply(context,[].concat.call(args, [].slice.call(arguments))) 里第二个参数为啥是
[].concat.call(args, [].slice.call(arguments))
, 它不就应该是 args 吗 ?
@lin-xin同问
Function.prototype.binding = function () {
let self = this;
let context = [].shift.call(arguments);
let args = [].slice.call(arguments);
console.log('Function binding args', args);
return function () {
self.apply(context, [].concat.call(args, [].slice.call(arguments)))
}
};
let obj = {
a: 'a'
};
function f(b, c, d) {
console.log(this.a, b, c, d)
}
f.binding(obj, 'b', 'c', 'd')('e');
f.binding(obj, 'b', 'c')('d', 'e');
f.binding(obj, 'b')('c', 'd', 'e');
f.binding(obj)('b', 'c', 'd', 'e');
输出:
Function binding args [ 'b', 'c', 'd' ]
a b c d
Function binding args [ 'b', 'c' ]
a b c d
Function binding args [ 'b' ]
a b c d
Function binding args []
a b c d
Process finished with exit code 0
从输出可以看出 args
是 f.binding
里除了第一个参数剩下所有的参数,而 [].slice.call(arguments)
是 f.binding
后第二个括号里的参数, args
的 this 是 Function.prototype.binding
,[].slice.call(arguments)
的 this 是 f.binding(obj)()
。
from blog.
完美,讲的很好
from blog.
@Fang0408 直接f(...arr)不就得了
from blog.
补充一个使用
apply
的例子。
比如求一个数组的最大值,使用Math.max
函数,但是这个函数入参不支持数组,只能是将多个参数逐个传入,用逗号分隔。let max = Math.max(1, 4, 8, 9, 0)有了
apply
,就可以这么调用:let arr = [1, 4, 8, 9, 0]; let max = Math.max.apply(null, arr);
Math.max(...[1,2,3])
from blog.
nice!
from blog.
@lin-xin 楼主这里有点问题吧 Person1.call(this) 的作用就是使用 Person1 对象代替 this 对象
,
Person1.call(this), 按照理解应该是 把Person1函数中的this指向了Person2中的this
from blog.
豁然开朗
from blog.
good
from blog.
nice!
from blog.
nice!
from blog.
var Person1 = function () {
this.name = 'linxin';
}
var Person2 = function () {
this.getname = function () {
console.log(this.name);
}
Person1.call(this);
}
var person = new Person2();
person.getname();
这个例子不是太理解,各位楼主有没有详细解答的
from blog.
在一定程度上Person1.call(this) 的作用就是使用 Person1 对象代替 this 对象是成立的,那样子的话Person2就不能拥有自己的属性了,我的理解是Person1.call(this)执行完毕后讲Person1的属性复制到了Person2中
from blog.
nice!
from blog.
if (!Function.prototype.bind) {
Function.prototype.bind = function () {
var self = this, // 保存原函数
context = [].shift.call(arguments), // 保存需要绑定的this上下文
args = [].slice.call(arguments); // 剩余的参数转为数组
return function () { // 返回一个新函数
self.apply(context,[].concat.call(args, [].slice.call(arguments)));
}
}
}
以上返回的函数体中的 self.apply(context,[].concat.call(args, [].slice.call(arguments))) 里第二个参数为啥是 [].concat.call(args, [].slice.call(arguments))
, 它不就应该是 args 吗 ?
@lin-xin
from blog.
好文,赞
from blog.
Perfect!
from blog.
@lin-xin 楼主这里有点问题吧
Person1.call(this) 的作用就是使用 Person1 对象代替 this 对象
,
Person1.call(this), 按照理解应该是 把Person1函数中的this指向了Person2中的this
返回的是一个函数,可以继续添加参数
from blog.
完全看不懂
from blog.
if (!Function.prototype.bind) { Function.prototype.bind = function () { var self = this, // 保存原函数 context = [].shift.call(arguments), // 保存需要绑定的this上下文 args = [].slice.call(arguments); // 剩余的参数转为数组 return function () { // 返回一个新函数 self.apply(context,[].concat.call(args, [].slice.call(arguments))); } } }以上返回的函数体中的 self.apply(context,[].concat.call(args, [].slice.call(arguments))) 里第二个参数为啥是
[].concat.call(args, [].slice.call(arguments))
, 它不就应该是 args 吗 ?
@lin-xin
同问
from blog.
if (!Function.prototype.bind) { Function.prototype.bind = function () { var self = this, // 保存原函数 context = [].shift.call(arguments), // 保存需要绑定的this上下文 args = [].slice.call(arguments); // 剩余的参数转为数组 return function () { // 返回一个新函数 self.apply(context,[].concat.call(args, [].slice.call(arguments))); } } }以上返回的函数体中的 self.apply(context,[].concat.call(args, [].slice.call(arguments))) 里第二个参数为啥是
[].concat.call(args, [].slice.call(arguments))
, 它不就应该是 args 吗 ?
@lin-xin同问
Function.prototype.binding = function () { let self = this; let context = [].shift.call(arguments); let args = [].slice.call(arguments); console.log('Function binding args', args); return function () { self.apply(context, [].concat.call(args, [].slice.call(arguments))) } }; let obj = { a: 'a' }; function f(b, c, d) { console.log(this.a, b, c, d) } f.binding(obj, 'b', 'c', 'd')('e'); f.binding(obj, 'b', 'c')('d', 'e'); f.binding(obj, 'b')('c', 'd', 'e'); f.binding(obj)('b', 'c', 'd', 'e');输出:
Function binding args [ 'b', 'c', 'd' ] a b c d Function binding args [ 'b', 'c' ] a b c d Function binding args [ 'b' ] a b c d Function binding args [] a b c d Process finished with exit code 0
从输出可以看出
args
是f.binding
里除了第一个参数剩下所有的参数,而[].slice.call(arguments)
是f.binding
后第二个括号里的参数,args
的 this 是Function.prototype.binding
,[].slice.call(arguments)
的 this 是f.binding(obj)()
。
明白了 多谢!
from blog.
if (!Function.prototype.bind) { Function.prototype.bind = function () { var self = this, // 保存原函数 context = [].shift.call(arguments), // 保存需要绑定的this上下文 args = [].slice.call(arguments); // 剩余的参数转为数组 return function () { // 返回一个新函数 self.apply(context,[].concat.call(args, [].slice.call(arguments))); } } }以上返回的函数体中的 self.apply(context,[].concat.call(args, [].slice.call(arguments))) 里第二个参数为啥是
[].concat.call(args, [].slice.call(arguments))
, 它不就应该是 args 吗 ?
@lin-xin同问
Function.prototype.binding = function () { let self = this; let context = [].shift.call(arguments); let args = [].slice.call(arguments); console.log('Function binding args', args); return function () { self.apply(context, [].concat.call(args, [].slice.call(arguments))) } }; let obj = { a: 'a' }; function f(b, c, d) { console.log(this.a, b, c, d) } f.binding(obj, 'b', 'c', 'd')('e'); f.binding(obj, 'b', 'c')('d', 'e'); f.binding(obj, 'b')('c', 'd', 'e'); f.binding(obj)('b', 'c', 'd', 'e');输出:
Function binding args [ 'b', 'c', 'd' ] a b c d Function binding args [ 'b', 'c' ] a b c d Function binding args [ 'b' ] a b c d Function binding args [] a b c d Process finished with exit code 0
从输出可以看出
args
是f.binding
里除了第一个参数剩下所有的参数,而[].slice.call(arguments)
是f.binding
后第二个括号里的参数,args
的 this 是Function.prototype.binding
,[].slice.call(arguments)
的 this 是f.binding(obj)()
。明白了 多谢!
这个是标准的闭包写法,函数嵌套函数的时候,被嵌套的函数的作用域链是单独的,而且每次执行外部函数时,这个作用域链总是会生成新的链,像this和arguments都不会和外部函数共享,也是单独的,比如嵌套函数想拿到外部的arguments和this需要在嵌套函数外面用变量做存储才可以,类似let self = this,let args = arguments。例子中嵌套函数的arguments就是自己函数的,而不是外部函数的。
Function.prototype.binding = function () {
let self = this;
let context = [].shift.call(arguments);
let args = [].slice.call(arguments);
console.log('Function binding args', args);
return function () {console.log('innerFunc',arguments);
self.apply(context, [].concat.call(args, [].slice.call(arguments)))
}
};
let obj = {
a: 'a'
};
function f(b, c, d) {
console.log(this.a, b, c, d)
}
f.binding(obj, 'b', 'c', 'd')('e');
f.binding(obj, 'b', 'c')('d', 'e');
f.binding(obj, 'b')('c', 'd', 'e');
f.binding(obj)('b', 'c', 'd', 'e');
Function binding args (3) ["b", "c", "d"]
innerFunc Arguments ["e", callee: ƒ, Symbol(Symbol.iterator): ƒ]
Function binding args (2) ["b", "c"]
innerFunc Arguments(2) ["d", "e", callee: ƒ, Symbol(Symbol.iterator): ƒ]
Function binding args ["b"]
innerFunc Arguments(3) ["c", "d", "e", callee: ƒ, Symbol(Symbol.iterator): ƒ]
VM1135:5 Function binding args []
innerFunc Arguments(4) ["b", "c", "d", "e", callee: ƒ, Symbol(Symbol.iterator): ƒ]
from blog.
懂了,真棒!!!
from blog.
if (!Function.prototype.bind) { Function.prototype.bind = function () { var self = this, // 保存原函数 context = [].shift.call(arguments), // 保存需要绑定的this上下文 args = [].slice.call(arguments); // 剩余的参数转为数组 return function () { // 返回一个新函数 self.apply(context,[].concat.call(args, [].slice.call(arguments))); } } }以上返回的函数体中的 self.apply(context,[].concat.call(args, [].slice.call(arguments))) 里第二个参数为啥是
[].concat.call(args, [].slice.call(arguments))
, 它不就应该是 args 吗 ?
@lin-xin同问
Function.prototype.binding = function () { let self = this; let context = [].shift.call(arguments); let args = [].slice.call(arguments); console.log('Function binding args', args); return function () { self.apply(context, [].concat.call(args, [].slice.call(arguments))) } }; let obj = { a: 'a' }; function f(b, c, d) { console.log(this.a, b, c, d) } f.binding(obj, 'b', 'c', 'd')('e'); f.binding(obj, 'b', 'c')('d', 'e'); f.binding(obj, 'b')('c', 'd', 'e'); f.binding(obj)('b', 'c', 'd', 'e');输出:
Function binding args [ 'b', 'c', 'd' ] a b c d Function binding args [ 'b', 'c' ] a b c d Function binding args [ 'b' ] a b c d Function binding args [] a b c d Process finished with exit code 0
从输出可以看出
args
是f.binding
里除了第一个参数剩下所有的参数,而[].slice.call(arguments)
是f.binding
后第二个括号里的参数,args
的 this 是Function.prototype.binding
,[].slice.call(arguments)
的 this 是f.binding(obj)()
。
既然 args已经 转化为数组了那最后的 :
`self.apply(context, [].concat.call(args, [].slice.call(arguments)))`
写成:
`self.apply(context, args.concat([].slice.call(arguments)))`
不是更方便
为什么还要调用一次call()呢
from blog.
let arr1 = [1, 2, 7, 5, 6];
let arr2 = [4, 7, 5, 4, 6, 8, ]
Array.prototype.push.apply(arr1, arr2)
还有添加
from blog.
在Person2中的 call 将Person1的指向改为 Person2中的实例 Person1 的 this.name 相当于写在了 Person2中
from blog.
Related Issues (20)
- Electron 实战桌面计算器应用 HOT 2
- HTML5 桌面通知:Notification API HOT 11
- Parcel:常见技术栈的集成方式 HOT 1
- Node.js 应用:Koa2 之文件上传下载 HOT 7
- React Native组件集成到Android原生项目 HOT 2
- 使用 Node.js 开发简单的脚手架工具 HOT 16
- Node.js 应用:Koa2 使用 JWT 进行鉴权 HOT 18
- 请教一下
- vue-manage-system 后台管理系统开发总结 HOT 2
- bind()实现中的 [].concat.call(args, [].slice.call(arguments) HOT 3
- 求博客主体模板 HOT 2
- 作者你好!H5 drop event
- element ui upload怎样修改缩略图路径
- indexedDB结合vuex store使用 HOT 1
- Rollup.js: 开源JS库的打包利器
- 前端常见的加密算法介绍 HOT 3
- file-demo 拍照,xs max照片旋转 HOT 2
- Vue3 插件开发详解尝鲜版
- vue项目中实现Excel文件的上传和下载
- vue3 + tsrpc +mongodb 实现后台管理系统 HOT 1
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.