>  기사  >  웹 프론트엔드  >  나를 따라와서 javascript 함수 호출 및 생성자 호출_javascript 기술을 배우십시오.

나를 따라와서 javascript 함수 호출 및 생성자 호출_javascript 기술을 배우십시오.

WBOY
WBOY원래의
2016-05-16 15:32:171230검색

1. 함수 호출
함수는 확실히 JavaScript에서 가장 중요한 것입니다. JavaScript에서 Function은 프로시저, 메소드, 생성자, 클래스 및 모듈의 기능을 가정합니다.

객체 지향 프로그래밍에서 함수, 메서드 및 클래스 생성자는 서로 다른 구문으로 구현되는 세 가지 다른 요소인 경우가 많습니다. 그러나 JavaScript에서는 이 세 가지 개념이 세 가지 다른 모드를 통해 함수로 구현됩니다.

가장 간단한 사용 모드는 함수 호출입니다.

function hello(username) { 
  return "hello, " + username; 
} 
hello("Keyser Söze"); // "hello, Keyser Söze" 

2. 메소드 호출

JavaScript에서 메소드의 개념은 객체의 속성이 함수라는 것입니다. 동일한 함수이지만 객체의 멤버에 할당한 후에는 다릅니다. 객체의 멤버에 함수를 할당한 후에는 더 이상 함수가 아니라 메서드라고 합니다.

var obj = { 
  hello: function() { 
    return "hello, " + this.username; 
  }, 
  username: "Hans Gruber" 
}; 
obj.hello(); // "hello, Hans Gruber" 

실제 동작은 호출 자체가 이것이 바인딩될 개체를 결정한다는 것입니다. 즉,
obj1.hello()는 이것을 obj1에 바인딩하고, obj2.hello()는 이것을 obj2에 바인딩합니다. 한 문장만 기억하세요. 누가 전화하든 누구를 가리킬 것입니다.

이 바인딩 규칙으로 인해 다음과 같은 사용법도 가능합니다.

function hello() { 
  return "hello, " + this.username; 
} 

var obj1 = { 
  hello: hello, 
  username: "Gordon Gekko" 
}; 
obj1.hello(); // "hello, Gordon Gekko" 

var obj2 = { 
  hello: hello, 
  username: "Biff Tannen" 
};_ 
obj2.hello(); // "hello, Biff Tannen" 

그러나 위의 hello 함수와 같은 일반적인 함수에서는 this 키워드를 직접 호출하는 경우에는 this를 가리키는 것이 문제가 됩니다. 이 경우 일반적으로 브라우저의 창 개체인 전역 개체(GlobalObject)를 가리키는 경우가 많습니다.
그리고 이 행동은 불확실하고 의미가 없습니다.

따라서 ES5 표준에서는 엄격 모드를 사용하면 정의되지 않음으로 설정됩니다.

function hello() { 
  "use strict"; 
  return "hello, " + this.username; 
} 
hello(); // error: cannot read property "username" of undefined 

위의 접근 방식은 잠재적인 오류를 더 빨리 노출하고 오작동과 찾기 어려운 버그를 방지하는 것입니다.
일반적인 함수 호출과 메서드 호출의 차이점은 이 예제를 보면 명확해집니다.

var func = function() {
  alert(this);
};
var o = {};
o.fn = func;
// 比较
alert(o.fn === func);//true
// 调用
func();//[object Window]
o.fn();//[object Object]

여기서 실행한 결과는 두 기능이 동일하므로 인쇄된 결과가 true입니다. 그러나 두 함수의 호출이 다르기 때문에 func를 호출하면 [object Window]가 인쇄되고, o.fn의 인쇄 결과는 [object Object]가 됩니다.

함수 호출과 메서드 호출의 차이점은 다음과 같습니다. 함수 호출에서 this는 구체적으로 전역 개체 창을 참조하는 반면, 메서드에서는 구체적으로 현재 개체를 참조합니다. 즉, o.fn의 this는 개체를 참조합니다. 영형.

3. 생성자 호출

함수의 세 번째 사용 모드는 생성자로 사용하는 것입니다.

생성자의

이것

이 의미를 알기 위해서는 객체 생성 과정을 분석해야 합니다.

 var Person = function() {
  this.name = "小平果";
 };
 var p = new Person();

여기서 Person 함수를 먼저 정의합니다. 전체 실행을 분석해 보겠습니다.

  • 프로그램이 이 문장을 실행할 때 함수 본문을 실행하지 않으므로 JavaScript 해석기는 이 함수의 내용을 알 수 없습니다.
  • 다음으로 new 키워드를 실행하여 객체를 생성합니다. 인터프리터는 메모리를 할당하고 객체에 대한 참조를 가져온 다음 새 객체에 대한 참조를 함수에 전달합니다.
  • 그런 다음 함수를 실행하고 전달된 객체 참조를 this에 전달합니다. 즉, 생성자 메서드에서 this는 new에 의해 방금 생성된 객체입니다.
  • 그런 다음 여기에 멤버를 추가합니다. 즉, 개체에 멤버를 추가합니다.
  • 마지막으로 함수가 종료되고 이를 반환한 후 왼쪽 변수에 전달합니다.

생성자의 실행을 분석해 보면 생성자에 있는 이것이 현재 객체라는 것을 알 수 있습니다.

생성자 반환

생성자에서 반환의 의미가 변경되었습니다. 먼저 생성자에서 객체가 반환되면 반환이 숫자, 부울 및 객체가 아닌 경우 원래 의미가 유지됩니다. 문자열인 경우 반환은 이것이고, 반환 문이 없으면 다음 코드도 반환됩니다.

 // 返回一个对象的 return
 var ctr = function() {
  this.name = "赵晓虎";
  return {
  name:"牛亮亮"
  };
 };
 // 创建对象
 var p = new ctr();
 // 访问name属性
 alert(p.name);

 //执行代码,这里打印的结果是"牛亮亮". 因为构造方法中返回的是一个对象,那么保留return的意义,返回内容为return后面的对象. 再看下面代码:

 // 定义返回非对象数据的构造器
 var ctr = function() {
  this.name = "赵晓虎";
  return "牛亮亮";
 };
 // 创建对象
 var p = new ctr();
 // 使用
 alert(p);
 alert(p.name);

코드를 실행한 결과 팝업창에는 먼저 [object Object]가 출력된 후 "Zhao Xiaohu"가 출력됩니다. 왜냐하면 여기서 return은 기본 유형에 속하는 문자열이기 때문입니다. 여기서는 유효하지 않으며 this 개체가 반환됩니다. 따라서 첫 번째는 [object Object]를 인쇄하지만 두 번째는 undefine을 인쇄하지 않습니다.

function User(name, passwordHash) { 
  this.name = name; 
  this.passwordHash = passwordHash; 
} 
var u = new User("sfalken", 
  "0ef33ae791068ec64b502d6cb0191387"); 
u.name; // "sfalken" 

새 키를 사용하여 함수를 생성자로 호출합니다. 함수 및 메소드 호출과 달리 생성자는 새 객체를 전달하고 여기에 바인딩한 다음 객체를 생성자의 반환 값으로 반환합니다. 생성자 함수 자체의 기능은 객체를 초기화하는 것입니다.

생성자 호출 시 흔히 발생하는 실수

다음 생성자를 행복하게 정의했습니다.

var Coder = function( nick ){ 
this.nick = nick; 
}; 

생성자를 정의한 후에는 어떻게 되나요? 맞습니다. 빠르게 인스턴스화하세요.

var coder = Coder( 'casper' ); 

이 코더 형제의 이름은 무엇입니까? 빠르게 인쇄하세요:

console.log( coder.nick ); //undefined 
= =b 竟然是undefined!!再回过头看看实例化的那个语句,不难发现问题出在哪里:少了个new 
var coder = Coder( 'casper' ); //当作普通的函数来调用,故内部的this指针其实指向window对象 
console.log( window.nick); //输出:casper 
var coder = new Coder( 'casper' ); //加上new,一切皆不同,this正确地指向了当前创建的实例 
console.log( coder.nick ); //输出:casper 

这样的错误貌似挺低级的,但出现的概率挺高的,肿么去避免或减少这种情况的发生呢?
可以在内部实现里面动下手脚:

var Coder = function( nick ){ 
  if( !(this instanceof Coder) ){ 
    return new Coder( nick ); 
  } 
    this.nick = nick; 
}; 

其实很简单,实例化的时候,内部判断下,当前this指向的对象的类型即可,如果非当前构造函数的类型,强制重新调用一遍构造函数。
突然觉得Coder这名字不够洋气?想用Hacker,好吧,我改。。。数了下,一共有三处要改,这不科学,有没有办法只把构造函数的名字改了就行?
当然有:

var Coder = function( nick ){ 
  if( !(this instanceof arguments.callee) ){ 
    return new arguments.callee( nick ); 
  } 
  this.nick = nick; 
}; 

tips:据说在ES 5的严格模式下面arguments.callee会被禁用,不过仅当ES 5普及同时你指定了要使用严格模式,否则还是可以用的发散下思维。

以上就是本文的全部内容,希望对大家学习函数调用、方法调用和构造函数调用有所帮助。

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.