试图在JavaScript中实现Python样式的len()

时间:2016-05-26 21:00:52

标签: javascript python call bind apply

我已经在JavaScript中阅读了很多关于// in a route // routes/route.js import Ember from 'ember' const { Route, getOwner } = Ember export default Route.extend({ model: function(){ return getOwner(this) .lookup('data-adapter:main') .getModelTypes() .map(type => type.name) } }) // somewhere else in an ember application const modelNames = getOwner(this) .lookup('data-adapter:main') .getModelTypes() .map(type => type.name) call()的内容,特别是关于此MDN article创建Shorcuts 部分。

我试图在JS中实现以下Python-esque函数:

bind()

我确实意识到这是一个人为的例子,但我试图绕过这些方法。以下是我实施的方式:

var arr = [1,2,3];
len(arr); // 3

当我运行它时,我得到:

var len = Function.prototype.call.bind( Array.prototype.slice.length );
len([1,2,3]);

我在这里想知道这是如何运作的?

1 个答案:

答案 0 :(得分:1)

当您设置变量len时,在您的代码中,您实际上是将len设置为函数Function.prototype.call的副本,并this(上下文Array.prototype.slice.length

我认为你误解了bind()的使用。假设我有一个函数len

var len = function() {
    return this.length;
};

你想得到一个数组的长度:

len.call([1,2,3]);

在这种情况下,this中的len是数组[1,2,3],因为我们使用call来提供this。假设我们想要将该数组永久绑定到该函数并将其存储在我们可以随时使用的变量中:

var myArrayLen = len.bind([1,2,3]);

现在,myArrayLen基本上是len的副本,永久绑定this [1,2,3]。如果我们调用它,则返回3.

在您的示例中,Array.prototype.slice.length实际上是函数Array.prototype.slice的长度,对应于number of arguments that can be passed to the function

没有内置的length()函数,所以为了遵循你的(诚然)设计的例子,我们只需要创建一个提供长度的函数,将它添加到数组原型中,然后使用{{1}绑定它。 }:

Function.prototype.apply.bind();