Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung der Methoden „Aufruf/Anwenden“, „Argumente“ und „Undefiniert/Null“ in JS

Detaillierte Erläuterung der Methoden „Aufruf/Anwenden“, „Argumente“ und „Undefiniert/Null“ in JS

高洛峰
高洛峰Original
2017-01-04 17:17:031338Durchsuche

Detaillierte Erläuterung der Methoden a.call und apply
----------------------------------- ----- --------------------------------------------- -----

call Methode:

Syntax: call([thisObj[,arg1[, arg2[, [,.argN]]]]])

Definition: Ein Objekt aufrufen Eine Methode, die das aktuelle Objekt durch ein anderes Objekt ersetzt.

Erläuterung: Mit der Call-Methode kann eine Methode anstelle eines anderen Objekts aufgerufen werden. Die Aufrufmethode ändert den Objektkontext einer Funktion vom Anfangskontext in das durch thisObj angegebene neue Objekt. Wenn kein thisObj-Parameter angegeben wird, wird das globale Objekt als thisObj verwendet.

Methode anwenden:

Syntax: apply([thisObj[,argArray]])

Definition: Ein Objekt eines bestimmten anwenden Objekt Methode, die das aktuelle Objekt durch ein anderes Objekt ersetzt.

 Hinweis: Wenn argArray kein gültiges Array oder kein Argumentobjekt ist, wird ein TypeError verursacht. Wenn weder argArray noch thisObj bereitgestellt werden, wird das globale Objekt als thisObj verwendet und es können keine Parameter übergeben werden.

Beispielstudie:

function add(a,b){ alert(a+b);}
function sub(a,b){ alert(a-b);}
add.call(sub,3,1);

Das gedruckte Ergebnis ist 4. Die Add-Funktion wird aufgerufen, aber das aufrufende Objekt (Kontext) ist nicht das Add-Objekt, sondern das Unterfunktionsobjekt. Hinweis: Funktionen in js sind eigentlich Objekte und der Funktionsname ist eine Referenz auf das Funktionsobjekt.

function Animal(){
this.name = "Animal";
this.showName = function(){ alert(this.name);}
}
function Cat(){ this.name = "Cat"; }
var animal = new Animal();
var cat = new Cat();
animal.showName.call(cat,",");//输出结果为"Cat"
animal.showName.apply(cat,[]);//输出结果为"Cat"

Aufruf bedeutet, die Tiermethode zur Ausführung auf cat zu setzen. Es stellt sich heraus, dass cat keinen showName() hat. Jetzt muss die showName()-Methode von animal zur Ausführung auf cat gesetzt werden, und this.name von cat ist Cat. Also sollte this.name Cat sein

Implementierungsvererbung

function Animal(name){
this.name = name;
this.showName = function(){ alert(this.name);}
}
function Cat(name){ Animal.call(this, name); }
var cat = new Cat("Black Cat");
cat.showName();

Animal.call(this) bedeutet den Aufruf der Animal-Methode, Wenn Sie jedoch dieses Objekt anstelle des Tierobjekts verwenden, wird der Kontext zu diesem. Animal.call wird in new Cat("Black Cat") verwendet, um den Attributnamen und die Methode showName für den aktuellen Kontext festzulegen.

Erweiterung: Mehrfachvererbung

function Class10(){
this.showSub = function(a,b){ alert(a-b); }
}
function Class11(){
this.showAdd = function(a,b){ alert(a+b); }
}
function Class2(){
Class10.call(this);
Class11.call(this);
}

Dies ist nicht Gegenstand dieses Artikels, aber ich erkläre hier nur die Verwendung von „call“. Apropos Aufruf, und natürlich bedeuten diese beiden Methoden im Grunde dasselbe. Der Unterschied besteht darin, dass der zweite Parameter von Aufruf von einem beliebigen Typ sein kann, während der zweite Parameter von Anwenden ein Array oder Argumente sein muss.

b.arguments verwenden


-------------------------- -- ------------------------------------------------ --


Was sind Argumente?

Argumente sind ein in JavaScript integriertes Objekt. Es ist seltsam und wird oft übersehen, aber es ist tatsächlich sehr wichtig. Alle wichtigen JavaScript-Bibliotheken verwenden das Argumentobjekt. Daher muss das Objekt agruments JavaScript-Programmierern bekannt sein.


Alle Funktionen verfügen über ein eigenes Argumentobjekt, das die aufzurufenden Parameter enthält. Es handelt sich nicht um ein Array. Wenn Typargumente verwendet werden, wird „Objekt“ zurückgegeben. Obwohl wir Argumente mit der Methode zum Aufrufen von Daten aufrufen können. Zum Beispiel Längen- und Indexmethoden. Array-Push- und Pop-Objekte sind jedoch nicht anwendbar.


Verwenden Sie Argumente, um eine flexible Funktion zu erstellen


Es scheint, dass die Verwendung des Argumentobjekts sehr eingeschränkt ist, aber tatsächlich ist es ein sehr nützliches Objekt. Sie können den Aufruf einer Funktion mit einer variablen Anzahl von Argumenten ermöglichen, indem Sie das Argumentobjekt verwenden. In der base2-Bibliothek von Dean Edwards gibt es eine Formatierungsfunktion, die diese Flexibilität demonstriert.


function format(string) {
var args = arguments;
var pattern = new RegExp('%([1-' + arguments.length + '])', 'g');
return String(string).replace(pattern, function(match, index,position,all) {
console.log(match + '&' + index + '&' + position + '&' + all);
return args[index];
});
};

Verwenden Sie stattdessen format('Und %1 möchte wissen, wessen %2 Sie %3', 'Papiere', 'Shirt', ' tragen'); das Ergebnis ist „Und die Zeitungen wollen wissen, wessen Hemd du trägst“; der Konsolendruck ist

 %1&1&8&Und die %1 wollen wissen, wessen %2 du %3

% 2&2&30&Und %1 möchte wissen, wessen %2 Sie %3
 %3&3&37&Und %1 möchte wissen, wessen %2 Sie %3


Konvertieren Sie das Argumentobjekt in ein echtes Array

Obwohl das Argumentobjekt kein echtes JavaScript-Array ist, können wir es dennoch problemlos in Standarddaten konvertieren und dann Array-Operationen ausführen.


var args = Array.prototype.slice.call(arguments);

Dann enthält die Variable args nun ein Standard-Javascript-Array-Objekt, das alle Parameter der Funktion enthält.

Erweiterung: Verwenden Sie die Formatfunktion im vorherigen Abschnitt, um eine Funktion


über das voreingestellte Argumentobjekt

function makeFunc() {
var args = Array.prototype.slice.call(arguments);
var func = args.shift();
return function() {
return func.apply(null, args.concat(Array.prototype.slice.call(arguments)));
};
}

zu erstellen method Der erste Parameter wird herausgenommen und dann wird eine Curry-Funktion zurückgegeben. Die Parameter der Curry-Funktion (die zweiten Argumente) werden mit den Parametern beginnend mit dem zweiten Parameter von makeFunc in einem neuen Array kombiniert. Und geben Sie den Apply-Aufruf des ersten Parameters von makeFunc zurück

Execute


var majorTom = makeFunc(format, "This is Major Tom to ground control. I'm %1.");
majorTom("stepping through the door");

Das Ergebnis ist: „This is Major.“ Tom zur Bodenkontrolle. Ich gehe durch die Tür.“

Konsolendruck: %1&1&41&Hier spricht Major Tom zur Bodenkontrolle. Ich bin %1.


[function.]arguments.callee

  说明:arguments.callee方法返回的是正在执行的函数本身。

  callee 属性是 arguments 对象的一个成员,它表示对函数对象本身的引用,这有利于匿名函数的递归或者保证函数的封装性,例如下边示例的递归计算1到n的自然数之和。而该属性仅当相关函数正在执行时才可用。还有需要注意的是callee拥有length属性,这个属性有时候用于验证还是比较好的。arguments.length是实参长度,arguments.callee.length是形参(定义时规定的需要的参数)长度,由此可以判断调用时形参长度是否和实参长度一致。

//用于验证参数
function calleeLengthDemo(arg1, arg2) {
if (arguments.length==arguments.callee.length) {
window.alert("验证形参和实参长度正确!");
return;
} else {
alert("实参长度:" +arguments.length);
alert("形参长度: " +arguments.callee.length);
}
}
//递归计算
var sum = function(n){
if (n <= 0) return 1;
else return n +arguments.callee(n - 1)
}
//比较一般的递归函数:
var sum = function(n){
if (1==n) return 1;
else return n + sum (n-1);
}

   

  调用时:alert(sum(100));其中函数内部包含了对sum自身的引用,函数名仅仅是一个变量名,在函数内部调用sum即相当于调用一个全局变量,不能很好的体现出是调用自身,这时使用callee会是一个比较好的方法。

拓展 functionName.caller 

  说明: 返回是谁调用了functionName 函数。functionName 对象是所执行函数的名称。对于函数来说,caller 属性只有在函数执行时才有定义。如果函数是由顶层调用的,那么 caller 包含的就是 null 。如果在字符串上下文中使用 caller 属性,那么结果和 functionName.toString 一样,也就是说,显示的是函数的反编译文本。 下面的例子说明了 caller 属性的用法:

// caller demo {
function callerDemo() {
if (callerDemo.caller) {
var a= callerDemo.caller.toString();
alert(a);
} else {
alert("this is a top function");
}
}
function handleCaller() {
callerDemo();
}
handleCaller();

   

  执行结果:

Detaillierte Erläuterung der Methoden „Aufruf/Anwenden“, „Argumente“ und „Undefiniert/Null“ in JS

c.undefined和null

--------------------------------------------------------------------------------

  大多数计算机语言,有且仅有一个表示"无"的值,比如,C语言的NULL,Java语言的null,Python语言的none,Ruby语言的nil。有点奇怪的是,JavaScript语言居然有两个表示"无"的值:undefined和null。这是为什么?

相似性

  在JavaScript中,将一个变量赋值为undefined或null,老实说,几乎没区别。

  代码如下:

var a = undefined;
var a = null;

   

  上面代码中,a变量分别被赋值为undefined和null,这两种写法几乎等价。

  undefined和null在if语句中,都会被自动转为false,相等运算符甚至直接报告两者相等。

if (!undefined)
console.log(&#39;undefined is false&#39;);
// undefined is false
if (!null)
console.log(&#39;null is false&#39;);
// null is false
undefined == null
// true

   

  上面代码说明,两者的行为是何等相似!但是我们去查看undefined和null的各自的类型却发现类型是不同的。js基础类型中没有null类型

typeof null;//"object"
typeof undefined;//"undefined"

   

  既然undefined和null的含义与用法都差不多,为什么要同时设置两个这样的值,这不是无端增加JavaScript的复杂度,令初学者困扰吗?Google公司开发的JavaScript语言的替代品Dart语言,就明确规定只有null,没有undefined!

历史原因

  原来,这与JavaScript的历史有关。1995年JavaScript诞生时,最初像Java一样,只设置了null作为表示"无"的值。

  根据C语言的传统,null被设计成可以自动转为0。

Number(null) // 0
5 + null // 5

  但是,JavaScript的设计者Brendan Eich,觉得这样做还不够,有两个原因。

  首先,null像在Java里一样,被当成一个对象。

typeof null // "object"

  但是,JavaScript的数据类型分成原始类型(primitive)和合成类型(complex)两大类,Brendan Eich觉得表示"无"的值最好不是对象。

  其次,JavaScript的最初版本没有包括错误处理机制,发生数据类型不匹配时,往往是自动转换类型或者默默地失败。Brendan Eich觉得,如果null自动转为0,很不容易发现错误。因此,Brendan Eich又设计了一个undefined。

最初设计

  JavaScript的最初版本是这样区分的:null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。

Number(undefined) // NaN
5 + undefined // NaN 

目前的用法

  但是,上面这样的区分,在实践中很快就被证明不可行。目前,null和undefined基本是同义的,只有一些细微的差别。

  null表示"没有对象",即该处不应该有值。典型用法是:

  (1) 作为函数的参数,表示该函数的参数不是对象。

  (2) 作为对象原型链的终点。

Object.getPrototypeOf(Object.prototype) // null

  undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:

  (1)变量被声明了,但没有赋值时,就等于undefined。

  (2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。

  (3)对象没有赋值的属性,该属性的值为undefined。

  (4)函数没有返回值时,默认返回undefined。

var i;
i // undefined
function f(x){console.log(x)}
f() // undefined
var o = new Object();
o.p // undefined
var x = f();
x // undefined

   

以上所述是小编给大家介绍的Detaillierte Erläuterung der Methoden „Aufruf/Anwenden“, „Argumente“ und „Undefiniert/Null“ in JS,希望对大家有所帮助。

更多Detaillierte Erläuterung der Methoden „Aufruf/Anwenden“, „Argumente“ und „Undefiniert/Null“ in JS相关文章请关注PHP中文网!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn