Home  >  Article  >  Web Front-end  >  Follow me to learn javascript function calls and constructor calls_javascript skills

Follow me to learn javascript function calls and constructor calls_javascript skills

WBOY
WBOYOriginal
2016-05-16 15:32:171229browse

1. Function call
Function is definitely the most important thing in JavaScript. In JavaScript, Function assumes the functions of procedures, methods, constructors and even classes and modules.

In object-oriented programming, functions, methods and class constructor are often three different things, implemented by different syntaxes. But in JavaScript, these three concepts are implemented by functions, through three different modes.

The simplest usage mode is function call:

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

2. Method calling

The concept of methods in JavaScript is that the attribute of an object is a function: it is the same function, but it is different after assigning it to a member of an object. After assigning a function to a member of an object, it is no longer called a function, but a method.

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

The real behavior is that the call itself determines which object this will be bound to, that is:
obj1.hello() will bind this to obj1, and obj2.hello() will bind this to obj2. Remember one sentence, whoever calls, this will point to whom

Because of this binding rule, the following usage is also feasible:

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" 

However, in an ordinary function, such as the hello function above, using the this keyword is not a good way. When it is called directly, the pointing of this becomes a problem. In this case, this is often pointed to the global object (GlobalObject), which is generally the window object on browsers.
And this behavior is uncertain and meaningless.

So in the ES5 standard, if strict mode is used, this will be set to undefined:

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

The above approach is to expose potential errors faster and avoid misoperations and hard-to-find bugs.
The difference between ordinary function calls and method calls will be clear by looking at this example.

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

The running result here is that the two functions are the same, so the printed result is true. However, since the calls of the two functions are different, the call of func prints [object Window], while the print result of o.fn is [object Object].

Here is the difference between function call and method call. In function call, this refers specifically to the global object window, while in method this refers specifically to the current object, that is, this in o.fn refers to the object o.

3. Calling the constructor

The third usage mode of function is to use it as a constructor:

this

in the constructor

We need to analyze the process of creating an object to know the meaning of this. As shown in the following code:

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

The function Person is first defined here. Let’s analyze the entire execution:

  • When the program executes this sentence, it will not execute the function body, so the JavaScript interpreter does not know the content of this function.
  • Next, execute the new keyword to create the object. The interpreter allocates memory, gets a reference to the object, and hands the reference to the new object to the function.
  • Then execute the function and hand the passed object reference to this. In other words, in the constructor method, this is the object just created by new.
  • Then add members to this, that is, add members to the object.
  • Finally, the function ends, returns this, and hands this to the variable on the left.

After analyzing the execution of the constructor, we can get that this in the constructor is the current object.

return in constructor

The meaning of return in the constructor has changed. First, if in the constructor, if an object is returned, then the original meaning is retained. If the return is a non-object, such as a number, Boolean, and string, then the return is this, if there is no return statement, then this is also returned. Look at the following code:

 // 返回一个对象的 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);

The result of running the code is that the pop-up window first prints [object Object], and then prints "Zhao Xiaohu". Because the return here is a string, which belongs to the basic type, then the return statement here is invalid and the this object is returned. Therefore The first one prints [object Object] but the second one does not print undefined.

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

Use the new key to call the function as a constructor. Unlike function and method calls, the constructor will pass in a new object and bind it to this, and then return the object as the return value of the constructor. The function of the constructor function itself is to initialize the object.

A common mistake in constructor calling

I happily defined the following constructor:

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

What happens after defining the constructor? That’s right, instantiate it quickly:

var coder = Coder( 'casper' ); 

What is the name of this coder brother? Print it quickly:

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普及同时你指定了要使用严格模式,否则还是可以用的发散下思维。

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

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn