2013-03-02 1 views
19

JavaScript 함수 개체가 있습니다.Javascript 함수 개체의 속성

var addNum = function(num1, num2) { 
     return num1 + num2; 
} 

지금 나는 위의 코드에 대한 프로토 타입 체인을 이해하고 싶었다

addNum.divide() 

에 액세스하려고합니다. 위의 예제에서 addNum은 divide(), Function.prototype, Object.prototype 순으로 검색됩니다.

하지만 내 질문은 위의 예에, ADDNUM가 분할() 검색 될 수있는 방법을

이 같은 것을 참조 하는가 ;

var addNum = function(num1, num2) { 

this.divide = function(){} 

      return num1 + num2; 
    } 

이 (ADDNUM가 분열 검색 할 것이라고 말했습니다 어디) 라인을 이해할 수 없었다

날 같은 이해를 도와주세요.

+0

내가 크롬에서 코드를 실행 , 그리고 그것은 말합니다 : 잡히지 않는 TypeError : 객체 함수 (num1, num2) { return num1 + num2; } '나누기'방법이 없습니다 – andri

+0

건축상의 문제가 아닙니까? 사실 divide는 addNum의 자식 함수가 아닙니다. 오히려 그것들은 부모 클래스/객체를 가지게 될 것이며 변수와 속성을 공유하고 그것들에 대해 수학을 할 수 있을까요? –

+0

http://doctrina.org/Javascript-Objects-Prototypes.html – testndtv

답변

48

이 질문에 대한 답변을 드릴 수는 없지만 약간의 통찰력을 줄 수는 있습니다. 다음 예제를 고려하십시오.

var Person = (function() { 
    var Person = function (name) { 
     this.name = name; 
    } 

    Person.greet = function() { 
     console.log("Hello!"); 
    } 

    Person.prototype = { 
     greet: function() { 
      console.log('Hello, my name is ' + this.name); 
     } 
    }; 
    return Person; 
})(); 

var bob = new Person("Bob"); 

Person.greet(); // logs "Hello!" 
bob.greet(); // logs "Hello, my name is Bob 

함수 개체 "Person"은 직접 '인사말'속성이있는 함수입니다. OOP 방식으로, Person 함수 (Person.greet())에서 직접 호출 할 수있는 정적 메서드로 생각할 수 있습니다. Person 생성자로부터 person 객체를 "인스턴스화"하면, 새로운 객체 "bob"은 이제 Person.prototype 객체의 메소드를 참조합니다. 이제 bob.greet()를 호출하면 프로토 타입 객체에서 greet 함수를 사용합니다.

희망이 있습니다.

var instance = new addNum(); 
instance.divide(); 

그러나 함수는 객체이기 때문에, 다음이 유효 할 것입니다 :이에서

var addNum = function(num1, num2) { 
     return num1 + num2; 
} 
addNum.divide = function() {} 

당신이 생성자 함수로 addNum를 사용한 경우

+0

이 예제가 마음에 들지만 실제로는 프로토 타입 상속 가능성을 잘 설명합니다. 자바 스크립트의 가능성과 프로토 타입 뒤에있는 아이디어를 보여주기 위해'Function' 생성자를 확장 할 수 있다고 설명하는 또 다른 비트를 추가했을 것입니다. 계승. 예를 들어 – gmaliar

+0

감사합니다. Person.prototype.constructor가 인사하는 이유는 없지만 Person은 그렇지 않습니까? 콘솔에 입력하면 – Martian2049

1

아니, 마지막 코드는 의미가 있습니다 케이스 divide은 자체 프로토 타입 중 하나가 아닌 addNum의 속성이됩니다.

+0

사실 나는 http://doctrina.org/Javascript-Objects-Prototypes.html에서이 내용을 읽습니다. – testndtv

+0

예, 맞습니다. 마지막 문장을 업데이트하여 조금 명확하게했습니다. –

0

prototypal 상속을 이해하는 것은 처음에는 다소 애매하지만 이름에서 알 수 있듯이 JavaScript에서 몇 가지 프로토 타입이 있으며 Function이 그 중 하나입니다.

새 기능을 만들 때마다 typeof 명령을 사용하여 유형을 확인할 수 있습니다. 귀하의 경우 :

var a = function(a,b) { return a + b; } 

그것은 "function"를 반환하므로 a 변수 이상의 메소드에 추가하는 방법에는 두 가지가 있습니다. @Keith Morris가 제안한 것처럼 새로운 생성자를 만들고 내부에 메서드를 포함하고 반환 할 수 있습니다. 이것은 또한 기본 방법이기 때문에 기본 객체를 표현하는 각 객체로 확장되는 프로토 타입 메소드로 기본 객체를 오염시키지 않기 때문에 선호됩니다.

의미, 내가 대신이 작업을 수행 할 경우 :

Function.prototype.divide = function(a, b) { return a/b; } 

내가 지금 할 수있는 a.divide(2, 1);을하고 2을 반환합니다. 그러나 예를 들어 jQuery을 사용하고 jQuery.divide(2,1)을 수행하는 경우 함수의 즉각적인 범위에서 찾을 수 있기 때문에 2을 얻게됩니다. 그렇지 않다면, 그것의 프로토 타입으로 갈 것입니다.

희망 사항이 좀 더 잘 설명해 주길 바랍니다.

17

은 그렇게 자신을 말하는 것처럼 : 당신이 함수 객체 있습니다. 의지에 기능을 할당 할 수있는 속성과 메소드 : : 함수 그냥 객체 리터럴, 배열, 또는 다른 어떤 같은 JS의 객체이다이 경우

var someAnonFunction = function(foo) 
{ 
    console.log(this); 
    console.log(this === someAnonFunction);//will be false most of the time 
}; 
someAnonFunction.x = 123;//assign property 
someAnonFunction.y = 312; 
someAnonFunction.divide = function() 
{ 
    console.log(this === someAnonFunction);//will be true most of the time 
    return this.x/this.y;//divide properties x & y 
}; 
someAnonFunction.divide(); 

, someAnonFunction에 의해 참조 함수 객체가 할당 된 익명 함수에 대한 참조는 divide (익명 함수에 대한 참조는 어쨌든 더빙이라고 부름)이라고합니다. 따라서 여기에는 프로토 타입 참여가 없습니다. 당신이 그렇게 자신을 말하고, 당신을 마음 : 아마도이 더 분명하다,

console.log(someAnonFunction.toString === Function.prototype.toString);//functions are stringified differently than object literals 
console.log(someAnonFunction.hasOwnProperty === Object.prototype.hasOwnProperty);//true 

을 또는 : 모든 개체를 다시 Object.prototype을 추적 할 수 있습니다, 그냥이 시도하는 방법/속성 호출에 해결 방법에 대한 간단한 계획을 JS의 값 :

[  F.divide  ]<=========================================================\ \ 
F[divide] ===> JS checks instance for property divide       | | 
/\ ||                   | | 
|| || --> property found @instance, return value-------------------------------| | 
|| ||                   | | 
|| ===========> Function.prototype.divide could not be found, check prototype | | 
||  ||                  | | 
||  ||--> property found @Function.prototype, return-----------------------| | 
||  ||                  | | 
||  ==========> Object.prototype.divide: not found check prototype?  | | 
||   ||                 | | 
||   ||--> property found @Object.prototype, return---------------------|_| 
||   ||                 |=| 
||   =======>prototype is null, return "undefined.divide"~~~~~~~~~~~~~~~|X| 
||                    \/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< TypeError can't read property 'x' of undefined 
그러므로 당신이 프로토 타입을 사용하여 작업을 위의 코드를 원한다면, 당신은 종류의 프로토 타입을 증대해야한다는, 다음

(이 경우, Function.prototype). 이것이 권장되지 않는다는 사실을 알고 계십시오. 실제로 "native" 프로토 타입을 자주 frown하려고합니다. 아직 : 두 경우 모두

Function.prototype.divide = function (a, b) 
{ 
    a = +(a || 0);//coerce to number, use default value 
    b = +(b || 1) || 1;//division by zeroe is not allowed, default to 1 
    return a/b; 
}; 
function someFunction() 
{ 
    return 'someString'; 
}; 
var another = function(a, b) 
{ 
    return a + b; 
}; 
someFunction.divide(12, 6);//will return 2 
another.divide(12, 4);//3 

는, 이름 (someFunction 또는 another)에 의해 참조되는 함수 객체가 발견되지 divide라는 속성, 검색됩니다. 그런 다음 해당 속성이있는 Function.prototype을 검색합니다.
그렇지 않은 경우 JS는 Object.prototype도 확인합니다. 실패하면 결국 오류가 발생합니다.

What makes my.class.js so fast? (프로토 타입 체인 거래)
Objects and functions in javascript (함수의 요점을 되풀이 <는 => < => 생성자 객체)
What are the differences between these three patterns of "class" definitions in JavaScript?을 : 나는 잠시 다시이 주제에 SO에 꽤 긴 답변을 게시 한


Javascript - Dynamically change the contents of a function (변수와 속성에 할당되고 컨텍스트가 변경된 익명의 함수에 막연히 닿아 있음)

+3

아스키 예술에 대한 upvote – angabriel

+0

나 Second ed-ed. –

2

012를 만들 수 있습니다 static 방법 A [A의 일종] 등 38,:

var addNum = function(num1, num2) { 
    addNum.divide = function(){return num1/num2;}; 
    return num1 + num2; 
} 
// now you first have to run addNum 
var onethirds = addNum(1,3); //=> 4 
addNum.divide(); //=> 0.333333... 

그러나 그것은 바람직하지 않습니다.더 나은 constructor 함수를 만들 :

function Pair(n1,n2){ 
    n1 = n1 || 1; 
    n2 = n2 || 1; 
    // create instance methods 
    this.add  = function(){return n1+n2;}; 
    this.divide = function(){return n1/n2;}; 
    this.multiply = function(){return n1*n2;} 
} 
var pair1 = new Pair(2,6) 
    ,pair2 = new Pair(1,2); 
pair1.add(); //=> 8 
pair2.divide(); //=> 0.5 
//etc. 

또는 더 프로토 타입 접근 (방법은 없습니다 모든 인스턴스 생성자의 프로토 타입에 추가됩니다) :

function Pair(n1,n2){ 
    this.n1 = n1 || 1; 
    this.n2 = n2 || 1; 
    // create prototype methods (once) 
    if (!Pair.prototype.add){ 
    var proto  = Pair.prototype; 
    proto.add  = function(){return this.n1+this.n2;}; 
    proto.divide = function(){return this.n1/this.n2;}; 
    proto.multiply = function(){return this.n1*this.n2;} 
    } 
} 

Reading stuff