a.call 및 적용 방법에 대한 자세한 설명
---------------------- ----- ------------------- -----
호출 방법:
구문: call([thisObj[,arg1[, arg2[, [,.argN]]]]])
정의: 개체 호출 현재 개체를 다른 개체로 바꾸는 메서드입니다.
설명: 호출 메소드를 사용하여 다른 객체 대신 메소드를 호출할 수 있습니다. call 메소드는 함수의 객체 컨텍스트를 초기 컨텍스트에서 thisObj가 지정한 새 객체로 변경합니다. thisObj 매개변수가 제공되지 않으면 전역 개체가 thisObj로 사용됩니다.
적용 방법:
구문: apply([thisObj[,argArray]])
정의: 특정 개체를 적용합니다. object 현재 개체를 다른 개체로 바꾸는 메서드입니다.
참고: argArray가 유효한 배열이 아니거나 인수 객체가 아닌 경우 TypeError가 발생합니다. argArray나 thisObj가 모두 제공되지 않으면 전역 개체가 thisObj로 사용되며 매개 변수를 전달할 수 없습니다.
예시 연구:
function add(a,b){ alert(a+b);} function sub(a,b){ alert(a-b);} add.call(sub,3,1);
인쇄된 결과는 4입니다. add 함수가 호출되었으나 호출한 객체(컨텍스트)가 add 객체가 아닌 하위 함수 객체입니다. 참고: js의 함수는 실제로 객체이며 함수 이름은 Function 객체에 대한 참조입니다.
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"
호출은 cat에 동물 메소드를 넣어 실행한다는 의미입니다. 컨텍스트는 cat입니다. 이제 동물의 showName() 메소드를 cat에 넣어서 실행하는 것이고, cat의 this.name은 Cat입니다. 따라서 this.name은 Cat
구현 상속
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)은 Animal 메서드 호출을 의미합니다. 하지만 Animal 객체 대신 이 객체를 사용하면 컨텍스트는 다음과 같습니다. Animal.call은 new Cat("Black Cat")에서 현재 컨텍스트에 대한 속성 이름과 showName 메서드를 설정하는 데 사용됩니다.
확장: 다중 상속
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); }
이 글의 범위는 아니지만 여기서는 call의 사용법만 설명하겠습니다. 호출과 적용에 대해 말하면 이 두 메서드는 기본적으로 동일한 의미입니다. 차이점은 호출의 두 번째 매개 변수는 모든 유형이 될 수 있지만 적용의 두 번째 매개 변수는 배열 또는 인수여야 한다는 것입니다.
b.인수 사용
인수란 무엇입니까
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]; }); };
대신 형식('그리고 %1은(는) %2이(가) %3 누구인지 알고 싶어합니다', '서류', '셔츠', ' wear'); 결과는 "그리고 신문은 당신이 누구의 셔츠를 입고 있는지 알고 싶어합니다"입니다. 콘솔 인쇄는
%1&1&8&그리고 %1은(는) 누구의 %2인지 알고 싶어합니다. % 2&2&30&그리고 %1은(는) 당신이 누구 %2인지 알고 싶어합니다. %3
%3&3&37&그리고 %1은 당신이 누구 %2인지 알고 싶어합니다. %3
인수 개체를 실제 배열로 변환하세요
var args = Array.prototype.slice.call(arguments);
이제 변수 args에는 함수의 모든 매개변수를 포함하는 표준 자바스크립트 배열 객체가 포함됩니다.
확장: 이전 섹션의 형식 함수를 사용하여 미리 설정된 인수 개체를 통해
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))); }; }
함수를 만듭니다. method 첫 번째 매개변수를 빼낸 후 카레 함수의 매개변수(두 번째 인수)를 makeFunc의 두 번째 매개변수부터 시작하는 매개변수와 결합하여 새로운 배열을 만듭니다. 그리고 makeFunc의 첫 번째 매개변수의 적용 호출을 반환합니다.
Executevar majorTom = makeFunc(format, "This is Major Tom to ground control. I'm %1."); majorTom("stepping through the door");
결과는 다음과 같습니다. "This is Major 톰이 지상 통제소로 갑니다."
콘솔 인쇄: %1&1&41&이 사람은 지상 통제실로 가는 톰 소령입니다. 저는 %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();
执行结果:
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('undefined is false'); // undefined is false if (!null) console.log('null is false'); // 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
以上所述是小编给大家介绍的JS의 호출/적용, 인수, 정의되지 않음/null 메서드에 대한 자세한 설명,希望对大家有所帮助。
更多JS의 호출/적용, 인수, 정의되지 않음/null 메서드에 대한 자세한 설명相关文章请关注PHP中文网!