Javascript 如果不实例化(new-ing';ing';)it:var a=Array.prototype.slice.call(参数),这怎么可能呢?
在函数内部的上下文中,以下是代码(基于将函数的“参数”放入数组的标准模式):Javascript 如果不实例化(new-ing';ing';)it:var a=Array.prototype.slice.call(参数),这怎么可能呢?,javascript,arrays,Javascript,Arrays,在函数内部的上下文中,以下是代码(基于将函数的“参数”放入数组的标准模式): var args=Array.prototype.slice.call(参数) 我正在努力研究这个问题(我是JavaScript的初学者,来自C#) 我知道slice是一种实例方法,因为它是数组的原型函数 我也明白这不是一个静态的“实用函数”,也就是说要使用它,你必须像这样newit:(示例)var myArray=newarray();myArray.slice(…) call在此处传递一个对象,以将上下文更改为参数
var args=Array.prototype.slice.call(参数)代码>
我正在努力研究这个问题(我是JavaScript的初学者,来自C#)
我知道slice
是一种实例方法,因为它是数组的原型
函数
我也明白这不是一个静态的“实用函数”,也就是说要使用它,你必须像这样new
it:(示例)var myArray=newarray();myArray.slice(…)代码>
call
在此处传递一个对象,以将上下文更改为参数的上下文
与此相关,我也不知道两者之间的区别
Array.prototype.slice.call([32,32121412])
和Array.prototype.slice([32,32121412])
不在call的上下文中
那么,我的问题是:
我只是不明白在实例和静态方法之间是如何工作的。。。那么,谁能解释var args=Array.prototype.slice.call(参数)的复杂性呢代码>
为什么不调用new
就可以使用此选项
为什么这是可能的?它不是一个静态方法,必须“更新”,并且只有在使用call
函数时才有效。。。(至少在我的C#心态中…数组.prototype.slice.call([32,32,121,412])
和数组.prototype.slice([32,32,121,412])
之间的区别在于,在第一种情况下,实际的数组[32,32,121,412]
成为调用的“this”对象。换句话说,它就像下面的代码:[32,32,121,412].slice()
。只要在原型上调用slice
,它就会在原型对象的上下文中执行,这可能没有任何用处。当您向对象的原型添加函数时,它就变成了可以在该对象的实例上使用的函数。该函数的上下文必须是实例。i、 e
Array.prototype.myFunction = function() {
alert( this[0] ); // this should refer to the Array instance
};
var x = new Array(1);
x[0] = 5;
x.myFunction(); // alerts 5
但是,有时您可能有一个类似于数组的结构,它不是数组的子类或实例(例如Arguments对象)。函数的调用方法所做的是将上下文更改为要调用的第一个参数。在本例中,对数组原型的函数调用call方法。实际上,Array.prototype.myFunction
只是上面代码块中定义的一个函数call
是一种可以在任何函数上调用以更改其上下文的方法。因此,您将有一个arguments对象,而不是数组实例作为上下文
function foo() {
Array.prototype.myFunction.call( arguments ); // arguments is [6]
// alerts 6
}
foo( 6 );
我想您可能对Java等有类的语言中的“实例”和“静态”方法的行为感到困惑。JavaScript的工作方式不同
您还对另一个问题感到困惑,即所有JS函数调用如何在被调用函数中设置this
(即设置函数可能尝试操作的对象)以及.call()
对设置this
有什么影响
.slice()
方法被定义为Array.prototype
的属性,而不是单个数组实例上的Java风格的“实例方法”。您可以调用Array.prototype.slice()
,而不需要使用new
创建的数组实例
当你说:
myArray.slice()
JS将首先查看.slice()
是否实际上是myArray
对象的一个方法,然后(假设它不是)它将查看它是否是数组原型的一个方法-它是,所以它运行该方法
当您使用“点”符号调用任何JS函数时,即myArray.slice()
,在该函数中,特殊变量this
将设置为对象<代码>此
是对函数应操作的对象的引用。但是,如果您使用.call()
调用JS函数,则在该函数中,此
将设置为作为参数传递给.call()
的对象。所以
myArray.slice()
说调用.slice()
并让它在myArray
上运行
var args = Array.prototype.slice.call(arguments);
说调用.slice()
并让它对参数进行操作
注意不要使用var myArray=new Array()代码>-最好说var myArray=[]代码>与C#/Java不同,函数实际上是JavaScript中的一流公民
一般来说:
这意味着没有必要对其进行“更新”。。因为它是自己的对象,所以它完全按原样工作
“新建”函数(一般意义上)只是将该函数的“this”值更改为它将被赋值的变量,然后返回它
在JavaScript中使用函数而不“更新”它是可能的,因为他们是JavaScript中的“一流公民”
在更深入的意义上,“新”就是这样做的:
它创建一个从MyConstructor.prototype派生的新对象
它将构造函数的“this”值分配给新对象
执行内部代码(向新对象/实例添加属性)
返回新对象
关于我从实例中学到的知识的额外说明:
它们不像构造函数那样具有.prototype属性
尽管它们有一个[[prototype]]属性,它是从MyConstructor.prototype派生的
重写实例中的属性会影响MyConstructor.prototype[property]…请参见此处可能重复的@xdazz:相同的代码,但不是相同的上下文问题。。他问为什么,我问这是怎么发生的。@JanCarloViray因为Array.prototype
也是一个