JavaScript - 理解方法

时间:2016-01-11 08:59:29

标签: javascript oop methods

我对理解方法原则有疑问 我理解功能,我知道

function hello() {
    alert('Hello World');
}  

相同
var hello = function() {
    alert('Hello World');
}  

现在,我的问题是什么 这是我的一个方法的对象。我不明白为什么 yarsLeft function people()内的function people(name, age) { this.name = name; this.age = age; this.yearsUntilRetire = yearsLeft; // this is confised for me } function yearsLeft() { var numYears = 65 - this.age; return numYears; } 不需要括号 我正在寻找一个合乎逻辑的解释。

var test = new people('Superman', 50);
test.yearsUntilRetire(); // I understand this code and calling a method in that way

创建对象

this.yearsUntilRetire() = yearsLeft

为什么我不能写this.yearsUntilRetire = yearsLeft();x*y + z + t - 10 = 0

3 个答案:

答案 0 :(得分:7)

当您使用没有括号(())的函数名称时,您将设置对函数本身的引用

当您在括号中使用相同的功能时,您正在执行功能。

因此这一行

this.yearsUntilRetire = yearsLeft;

设置yearsUntilRetire指向该功能。此后你可以这样做:

this.yearsUntilRetire(); // execute the yearsLeft function.
  

为什么我不能写这个.yearsUntilRetire()= yearsLeft或this.yearsUntilRetire = yearsLeft();

在第一种情况下,您不能将调用函数的结果设置为不同的结果 - 这是语法错误。

在第二种情况下,您可以 - 它将变量yearsUntilRetire设置为调用函数yearsLeft的结果

答案 1 :(得分:1)

1) function hello() {alert('Hello World');} var hello = function() {alert('Hello World');}

不同

第一个是函数声明。第二个是分配给名为hello的变量的函数表达式。但是当然在使用这两个函数时,您可以将其视为相同且两者的行为相同。

2)函数将始终被调用,如函数名称后跟括号,例如:yearsLeft()。这是调用函数的唯一方法。

函数是JS中的First Class对象。它可以声明,表达,分配,传递给另一个函数并从函数返回。

因此,在您的情况下,您的目的是将全局函数yearsLeft分配给对象属性yearsUntilRetire。您完成任何其他任务的方式 - 记住" 功能是头等对象"

答案 2 :(得分:1)

以下是一些工作示例,用于说明问题的答案。 请参阅内联注释以获得解释。

console.assert( typeof helloWorldAsVar === 'function', 'helloWorldAsVar is defined' );
console.log( helloWorldAsVar );
console.assert( typeof helloWorld === 'function', 'helloWorld is defined' );
// creating a function like helloWorld means it will be hoisted to the top of the file as js does two passes
// when compiling the script. one to declare all the functions and initialize all the variables as undefined.
// and another to run through the code.
console.log(helloWorld);


var helloWorldAsVar = function() {
  return 'this will not get hoisted, and the function name is anonymous';
}
// helloWorldAsVar is only available after it is declared.
console.assert(typeof helloWorldAsVar === 'function', 'helloWorldAsVar is defined');
console.log( helloWorldAsVar );

function helloWorld() {
  return 'this will get hoisted to the top of the function, and it will keep its name';
}
<script src="http://codepen.io/synthet1c/pen/WrQapG.js">
</script>

// this is a constructor function, it is essentially a typed object that can
// have it's own methods similar to an oop class in other languages like php or java
// the convention is to name a constructor with the first letter capitalized and it should be singular
function Person(name, age) {
  // here you are assigning properties to your People object
  this.name = name;
  this.age = age;
  // you are passing a reference to the yearsLeft function
  // this.yearsUntilRetire = yearsLeft;
}

// a more standard way to add the yearsLeft function is to 
// use the People.prototype object which get's methods delegated to it eg.
Person.prototype.yearsUntilRetire = yearsLeft;

function yearsLeft() {
  var numYears = 65 - this.age;
  return numYears;
}

// Create objects
var superman = new Person('Clark', 50 ),
    batman = new Person('Bruice', 40 );

console.log( superman, 'yearsUntilRetire', superman.yearsUntilRetire() );
console.log( batman, 'yearsUntilRetire', batman.yearsUntilRetire() );

// Why I can 't write this.yearsUntilRetire() = yearsLeft or this.yearsUntilRetire = yearsLeft();
console.assert(this === window, 'this in the global context refers to the window object' );
console.assert(superman instanceof Person, 'superman is a Person' );
console.assert(batman instanceof Person, 'batman is a Person' );
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>