js closure function

Closure function

What is the closure function?

Closures way function is a function using, as the most common:

function fn1(){
    function fn(){

    }
    return fn;
}

This nested function is a function closure benefits of this model is that it gives access to the inner function variable outer function, and the function does not lead to the overall execution of the function is finished and destroyed.

E.g:

function fn1(){
    var a =10;
    function fn(){
        console.log(a); // 10
    }
    return fn;
}

Another example is the following code, with each execution of the function, the value of the variable will be incremented by 1, the reason is because the variable is a function of the outer scope chain among the inner function is used with the inner function, when js garbage collection will not read into this situation after garbage collection.

E.g:

function fn1(){
    var a = 1;
    function fn(){
        a++;
        console.log(a);
    }
    return fn;
}

// 调用函数
var x  = fn1();
x(); // 2
x();//3

Js closure function in the development are very common among the writing, for example, following such an approach, some of the functionality is implemented on the package of the normal operation of the array, also belong to an application of closure function.

let Utils = (function(){
    var list = [];
    return {
        add:function(item){
            if(list.indexOf(item)>-1) return; // 如果数组内元素存在,那么不在重复添加
            list.push(item);
        },
        remove:function(item){
            if(list.indexOf(item) < 0) return; // 如果要删除的数组数组之内不存在,那么就返回
            list.splice(list.indexOf(item),1);
        },
        get_length:function(){
            return list.length;
        },
        get_showData:function() {
            return list;
        }
    }
})();
Utils.add("hello,world");
Utils.add("this is test");
console.log(Utils.get_showData());// ["hello,world","this is test"]

In the above code, the function nested function closure structure is formed functions, it is written in the more common development.

Concept closure package:

闭包是指有权限访问上一级父作用域的变量的函数.

Immediate execution function (IIFE)

In js development, which often run into 立即执行函数the wording. Roughly as follows:

// 下面的这种写法就是立即执行函数
// 在函数内部的内容会自动执行
(function(){
    var a = 10;
    var b = 20;
    console.log(a+b); // 30
})();

We can also pass through the second parameter in parentheses:

(function(i){
    console.log(i);
})(i);

This wording is essentially on the terms of the call is from a 闭包函数.

With this closure function, we can effectively avoid the pollution problems variables to create an independent scope.

But the problem is also relatively obvious, it is in the scope of which independent, we have no way of functions or variables which will allow external access to. So if we need external
access to the immediate implementation of a variable or function method, we need to enclose the second window of the global variable object passed, and will need to access the external variable or function assigned
to the window, to do so It corresponds to expose the scope of the global range.

Note that, under normal circumstances we only need to expose the necessary means, so as to ensure that the code does not produce too much influence each other, thereby reducing the degree of coupling.

E.g:

(function (window){
    var a = 10; // 私有属性

    function show(){
        return a++;
    }


    function sayHello(){ // 私有方法
        alert("hello,world");
    }
    window.show = show;// 将show方法暴露在外部
})(window);

It is to be understood that many code, always in front (function () {}) ( ) plus a ;purpose is to prevent the coalescence of the code when the code will be parsed into js (function(){})()(function(){})()case.

Variation closure function

Because of the special nature of js, so many times when we learn js, in addition to grammar js code, but also learn a lot of programs in order to solve practical problems, such as the following such an approach is to
achieve modulethe wording.

E.g:

var testModule = function(){
    var name = "张三"; // 私有属性,外部无法访问

    return {
        get_name:function(){ // 暴露在外部的方法
            alert(name);
        },
        set_name:function(new_name){ // 暴露在外部的方法
            name = new_name;
        }
    }
}

We can also upgrade such an approach, and execute the function immediately appropriate combination is a common wording:

E.g:

var blogModule = (function (my) {
    my.name = "zhangsan";
    // 添加一些功能   
    my.sayHello = function(){
        console.log(this.name)
    }
    return my;
} (blogModule || {}));  

console.log(blogModule.sayHello())

Since the calling function (self-executing anonymous function (Self-executing anonymous function)) and perform the function of the difference immediately

In fact, since the calling function is a recursive function

Since calling a function name suggests, it is to call its own function, and the function is executed immediately and the function will be executed immediately.

Here are some comparison between the two:

// 这是一个自执行的函数,函数内部执行自身,递归
function foo() { foo(); }

// 这是一个自执行的匿名函数,因为没有标示名称
// 必须使用arguments.callee属性来执行自己
var foo = function () { arguments.callee(); };

// 这可能也是一个自执行的匿名函数,仅仅是foo标示名称引用它自身
// 如果你将foo改变成其它的,你将得到一个used-to-self-execute匿名函数
var foo = function () { foo(); };

// 有些人叫这个是自执行的匿名函数(即便它不是),因为它没有调用自身,它只是立即执行而已。
(function () { /* code */ } ());

// 为函数表达式添加一个标示名称,可以方便Debug
// 但一定命名了,这个函数就不再是匿名的了
(function foo() { /* code */ } ());

// 立即调用的函数表达式(IIFE)也可以自执行,不过可能不常用罢了
(function () { arguments.callee(); } ());
(function foo() { foo(); } ());

The scope and the scope chain

  1. Scope

So-called 作用域, it refers to 变量and 函数the 可访问范围control variables and functions of the visibility and lifecycle
scoped variables have JavaScript 全局作用域and 函数作用域well ES6 newly added 块级作用域.

For example, the external functions through varis a global variable, i.e. the end of the scope keyword variable declared global scope, and inside the function
by vardeclaration or letis a local variable declaration, the scope is limited to internal functions in the {}inside or flow control statement or internal loop
through the letscope of the variable scope statement is limited to the current scope. Function parameters in the ()inside, only internally used function, the scope is limited to the range of functions.
At the same time windowall the attributes of an object also has a global scope.

E.g:


// 作用域范围
var a = 10; // 全局

function fn1(a,b){ // 函数fn1内

    c = 30; // 全局
    var x = 30; // 函数fn1内  

    function fn2(){
        var s = "hello"; // 函数fn2内
        console.log(x); // 30 函数内部可以访问外层的变量
    }
}

for(var i =0;i<10;i++){} // 循环体内声明的计数变量i也是一个全局

console.log(i); // 10

for(let j = 0;i<10;j++){} // let 声明的计数变量j 是一个局部  

console.log(j);// 出错,访问不到
  1. Execution Context

Above, we talk about the scope, then for the next execution environment (execution context).

What is the execution environment?

Simply put, the execution environment defines a variable or function has access to other data, and also determine their own behavior. Need to know
is that each execution environment, have an associated variable object (variable object), execution environment defined variables and functions will be saved in this object, the parser when processing data access the internal object.

The global execution environment is the outermost layer of an execution environment in the web browser, the outermost layer of the object is associated execution environment window, so we
can say that all the global variables and functions are as properties and methods of the window object created.

We create each function has its own execution environment, when the execution flow to function, environmental function will be pushed into a function execution stack
them, and popped the execution environment after the function is finished and destroyed, all variable and function definitions stored in them will be destroyed, the execution environment control returns to the previous, the global execution environment in the application exits (the browser is closed) will be destroyed.

  1. The scope chain

When code is an execution environment to execute it, it creates a variable object of a scope chain (scope chain), to ensure execution environment
, orderly access variables and functions have access to the execution environment.

Scope d is also the first top-level object is always variable object code environment where (VO) currently executing.

E.g:

function fn1(){}

fn1 be added to the global object when creating the scope chain, the global object has all of the global variables.

Such as the above fn1 when it is created, the environment is the global environment, so at this point it's this window.

Parsing function identifier during a search operation is the process along a scope chain, starting from the first object, step by step back backwards until you find the same name identifier up, after finding no longer continue to traverse, can not be found on the error.

If the execution environment is a function, then it is an active object (activation object, AO) the first object as the scope chain, the second object comprising the environment, the environment comprising the next layer containing environment ...

That so-called scope chain, refers specifically to a variable or function from the first object (active object) up to the top-level execution environment. This link is the middle of the scope chain.

Being 误解the closure function

Turning to the concept of closure package function, often someone wrong to be construed as an internal function return from the parent context, only the anonymous function can even be understood as a closure.

Actually, because the scope chain, so that all functions are closures (regardless of the type of function: anonymous function, FE, NFE, FD are closures).

Note: except there is only one class of functions that is created via Function constructor function because of its [[Scope]] contains only global object.

Application package closure function

Closure function is a very important concept js which, in many places can be applied to the closure by the closure, we can write a lot of good code, here are some common elements:

E.g:

// 数组排序
[1, 2, 3].sort(function (a, b) {
  ... // 排序条件
});

// map方法的应用,根据函数中定义的条件将原数组映射到一个新的数组中
[1, 2, 3].map(function (element) {
  return element * 2;
}); // [2, 4, 6]

// 常用的 forEach
[1, 2, 3].forEach(function (element) {
  if (element % 2 != 0) {
    alert(element);
  }
}); // 1, 3

For example, we call and apply conventional methods, they are two 应用函数, that is applied to the function parameters (parameter list apply, the parameters are independent of the call):

E.g:

(function () {
  alert([].join.call(arguments, ';')); // 1;2;3
}).apply(this, [1, 2, 3]);

There are most commonly used wording:

var a = 10;
setTimeout(function () {
  alert(a); // 10, after one second
}, 1000);

Of course, ajax wording is, in fact, the essence of the callback function is closure:

//...
var x = 10;
// only for example
xmlHttpRequestObject.onreadystatechange = function () {
  // 当数据就绪的时候,才会调用;
  // 这里,不论是在哪个上下文中创建
  // 此时变量“x”的值已经存在了
  alert(x); // 10
};
//...

Of course we said above also includes a separate package scope wording:

E.g:

var foo = {};

// 初始化
(function (object) {

  var x = 10;

  object.getX = function _getX() {
    return x;
  };

})(foo);

alert(foo.getX()); // 获得闭包 "x" – 10

 JSON objects and objects directly amount JS

In the work which we always hear people say can convert the data to JSON objects, or to convert JSON object to a string that kind of thing, here is a specific description of the JSON.

 JSON objects are not JavaScript object literal (Object Literals)

Many people mistakenly believe that is the object of the JSON literal (object Literals) JavaScript them, and the reason is very simple, it is because their syntax is very similar, but in the ECMA clearly illustrates. JSON is just a data exchange language, we will only use it in the context of its time string called JSON.

Serialization and de-serialization

When two (or server, language, etc.) require interactive communication, because they tend to use string string string in many languages ​​analytical methods are similar. Complex data structures often need to use, and by various brackets {}, parentheses (), called the brackets <> to compose and spaces, the string is just good character in accordance with specification requirements.

To this end, we have to describe these complex data structure as a string string, set standards and rules of grammar. JSON just one syntax that describes objects, arrays, strings, numbers, Boolean and null string in the context, and then through the inter-program transmission, and deserialized into the required format.

Common popular interactive data format YAML, XMLand JSONare commonly used data interchange format.

Literal
reference Mozilla Developer Center in a few words, for your reference:

  1. They are fixed values, not variables, so you from "literally" Understanding script. (Literals)
  2. String literal is a double quotation mark ( ") or a single quote ( ') surrounded by zero or more characters. (Strings Literals)
  3. Object literal by braces ({}) enclose the attribute name of zero or more objects - value pairs. (Object Literals)

When will become JSON

JSON is designed to describe data exchange format, he also has its own grammar, the syntax is a subset of JavaScript.
{ "Prop": "val" } This statement may be the JavaScript object literal string JSON also possible, depending on what context to use it, if it is used in a string context (with single or double quotation marks, or text file read) from, then it is JSON string, if it is used in a context object literal, then it is the object literal.

E.g:

// 这是JSON字符串
var foo = '{ "prop": "val" }';

// 这是对象字面量
var bar = { "prop": "val" };

But also to pay attention to, JSON has a very strict syntax in string contexts { "prop": "val"} is a legitimate JSON, but {prop: "val"} and { 'prop': 'val'} does not legitimate of. All attribute name and its value must be incorporated in double quotation marks, not to use single quotes.

JS among the JSON object

Currently, JSON objects has become JS among a built-in objects, there are two static methods: JSON.parse and JSON.stringify.

JSON.parse main JSON string to be deserialized into objects, JSON.stringify object to serialize JSON string. Older versions of browsers do not support this object, but you can achieve the same function by json2.js.

E.g:

// 这是JSON字符串,比如从AJAX获取字符串信息
var my_json_string = '{ "prop": "val" }';

// 将字符串反序列化成对象
var my_obj = JSON.parse( my_json_string );

alert( my_obj.prop == 'val' ); //  提示 true, 和想象的一样!

// 将对象序列化成JSON字符串
var my_other_json_string = JSON.stringify( my_obj );

Creating objects

Create objects in javascript There are a variety of ways, as follows:

  1. The first way is to create an object constructor function of the form
  2. The second form is through {}direct such an approach to create an object

    Another is to create a constructor by new Object () form.

Create an object in the form of an object literals

E.g:

let obj = {
    value:10,
    setValue:function(new_value){
        this.value = new_value;
    },
    geyValue:function(){
        return this.value;
    }
}

Create an object in the form of the constructor

E.g:

function Person(name,age){
    this.name = name;
    this.age = age;
}

var a = new Person("张三",30);

() To create an object by new Object

E.g:

var obj = new Object();

console.log(obj); // {}

Use object objects directly created with a

Here's some of what use objects created by the amount of the object directly:

Additions change search attributes and methods:
For example:

// 创建一个对象直接量
var person = {
    name:"张三",
    age:40,
    sayHello:function(){
        alert(this.name,"你好");
    },
    setName:function(name){
        this.name = name;
    }
}

// 更改属性
person.name = "李四";
person['age'] = 40;

// 更改方法
person.sayHello = function(){
    return this.name + "你好";
}


// 添加属性
person.like = "旅游";

// 添加方法
person.run = function(){
    return `${this.name} 正在跑步`;
}

// 删除
delete person.age;

// 查询和调用
console.log(person.name);

console.log(person.run());

Object constructor creates a common mode of operation

E.g:

function Person(name,age){
    this.name = name; // 初始化属性
    this.age = age;
}

Person.prototype.sayHello  = function(){
    alert(this.name);
}

// 实例化
var zhangsan = new Person("张三",20);

// 查看属性
console.log(zhangsan.name);

//. 调用方法
zhangsan.sayHello();

// 修改属性
zhangsan.name = "张小三";

// 修改方法
zhangsan.sayHello = function(){
    console.log(this.name + "你好");
}


// 添加属性和调用属性相同 ...
// 添加方法和调用方法相同 ...

// 删除
delete zhangsan.name;
console.log(zhangsan);

Object getter and setter

Js objects in them, there are two properties getter and setter, we can query attributes and assignment by these two attributes.

E.g:

var obj =  {
    value:10,

    get add(){
        return this.value + 1;
    },
    set changeVal(new_val){
        return this.value = new_val;
    }
}

// 使用
console.log(obj.add); // 11
obj.changeVal = 20;
console.log(obj.value); // 20

Application: Variable monitor

For example:
HTML code is as follows

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>变量的动态监听</title>
</head>
<body>
    <button id="btn" onclick="test()">点击</button>
    <p id="p">0</p>
</body>
<script src="test.js" charset="utf-8"></script>
<script type="text/javascript">
    function test(){
        watchVal.value = ++watchVal.value;
        let info = document.getElementById("p");
        info.innerHTML = watchVal.value;
        console.log(watchVal.value);
    }
</script>
</html>

js code as follows:

// 变量监听
var watchVal = {
    value:0,
    get val(){
        console.log('取值:',this.value);
        return this.value;
    },
    set val(vals) {
        this.value = vals;
        console.log("存储之后的值",this.value);
    }
}

Prototype and prototype chain

In many object-oriented programming language which, 封装, 继承, 多态it is the essential content, and in this door js object-based programming language who want to achieve their many features, only
through prototypeto prototyping.

We can first be by a simple code to experience the prototype:

// 创建一个数组
var arr = [1,2,3,4];

// 打印这个数组
console.log(arr);

You can see the final result in a property in print __proto__.

You had you try to print, you will find that contains Arrayproperties and methods.

What is it?

It is actually the data arr 数组prototype, and __proto__expressed the array is actually the prototype chain.

You need to know is that in js them, __proto__is to represent the prototype of the data, we can create an array of add to us through its methods:

E.g:

// 创建一个数组
var arr = [1,2,3,4];

// 打印这个数组
console.log(arr);

// 向数组的原型上添加一个sayHello()方法
arr.__proto__.sayHello = function(){
    console.log("hello,world!");
}

arr.sayHello();

We in the development process, the more is the use of the following wording:

// 创建一个数组
var arr = [1,2,3,4];

// 打印这个数组
console.log(arr);

// 向数组的原型上添加一个sayHello()方法
Array.prototype.sayHello = function(){
    console.log("hello,world!");
}

arr.sayHello();

In the above code, prototypealso said the prototype, but more often is applied on the body of the constructor. ArrayIs the prototype of an array of objects
, it is a constructor, it can be set by the method of this property.

When the data is, when a constructor, prototype of use can also be simplified:


function Person(){

}

Person.prototype = {
    sayHello:function(){
        console.log(111)
    }
}


var a = new Person();
a.sayHello();

Object-Oriented

In the field of programming, object-oriented programming paradigm is a common, also known as OOP, ECMASript of the support structure comprises, object-oriented, functional, and other imperative programming.

Here to say is that object-oriented programming content.

MDN Description:

面向对象编程是用抽象方式创建基于现实世界模型的一种编程模式。它使用先前建立的范例,包括模块化,多态和封装几种技术。今天,许多流行的编程语言(如Java,JavaScript,C#,C+ +,Python,PHP,Ruby和Objective-C)都支持面向对象编程(OOP)。

相对于「一个程序只是一些函数的集合,或简单的计算机指令列表。」的传统软件设计观念而言,面向对象编程可以看作是使用一系列对象相互协作的软件设计。 在 OOP 中,每个对象能够接收消息,处理数据和发送消息给其他对象。每个对象都可以被看作是一个拥有清晰角色或责任的独立小机器。

面向对象程序设计的目的是在编程中促进更好的灵活性和可维护性,在大型软件工程中广为流行。凭借其对模块化的重视,面向对象的代码开发更简单,更容易理解,相比非模块化编程方法, 它能更直接地分析, 编码和理解复杂的情况和过程。

Object-oriented programming terms:

Namespace 命名空间
    允许开发人员在一个独特,应用相关的名字的名称下捆绑所有功能的容器。
Class 类
    定义对象的特征。它是对象的属性和方法的模板定义。
Object 对象
    类的一个实例。
Property 属性
    对象的特征,比如颜色。
Method 方法
    对象的能力,比如行走。
Constructor 构造函数
    对象初始化的瞬间,被调用的方法。通常它的名字与包含它的类一致。
Inheritance 继承
    一个类可以继承另一个类的特征。
Encapsulation 封装
    一种把数据和相关的方法绑定在一起使用的方法。
Abstraction 抽象
    结合复杂的继承,方法,属性的对象能够模拟现实的模型。
Polymorphism 多态
    多意为「许多」,态意为「形态」。不同类可以定义相同的方法或属性。

JS among namespace

Namespace is a container that allows developers a unique, specific binding all feature in the name of the application. In JavaScript, comprising namespace just another method, object attributes, object.

JavaScript to create space behind the naming of the idea is simple: a global object is created, all of the variables, methods and functions become property of the object. Using namespaces also minimizes the possibility of the application of a name conflict.

For example:
Let's create a global variable called MYAPP

// 全局命名空间
var MYAPP = MYAPP || {};

In the code example above, we first check whether MYAPP has been defined (whether in the same file or in another file). If so, then use the existing MYAPP global object, otherwise, create an empty object called MYAPP of used packaging methods, functions, variables and objects.

We can also create sub-namespaces:

// 子命名空间
MYAPP.event = {};

The following are used to create a namespace and add the code writing variables, functions and methods:

// 给普通方法和属性创建一个叫做MYAPP.commonMethod的容器
MYAPP.commonMethod = {
  regExForName: "", // 定义名字的正则验证
  regExForPhone: "", // 定义电话的正则验证
  validateName: function(name){
    // 对名字name做些操作,你可以通过使用“this.regExForname”
    // 访问regExForName变量
  },

  validatePhoneNo: function(phoneNo){
    // 对电话号码做操作
  }
}

// 对象和方法一起申明
MYAPP.event = {
    addListener: function(el, type, fn) {
    //  代码
    },
   removeListener: function(el, type, fn) {
    // 代码
   },
   getEvent: function(e) {
   // 代码
   }

   // 还可以添加其他的属性和方法
}

//使用addListener方法的写法:
MYAPP.event.addListener("yourel", "type", callback);

Custom object

[Class]
JavaScript is a prototype-based language, it is not the class declaration, such as C + + or Java used in the. This class will sometimes have the habit of using language programmers declare statement generation problems. Instead, JavaScript can be used as a class method. Define a class with the same simple definition of a function. In the following example, we define a new class of Person.

function Person() { }
// 或
var Person = function(){ }

[(Instance of the class) Object]

We use new obj create a new instance of the object obj, and the result (obj type) assigned to a variable facilitate the call later.

In the following example, we define a class named Person and we create two instances of Person (person1 and person2).

function Person() { }
var person1 = new Person();
var person2 = new Person();

[Constructor]

In the instance of the constructor is called (that is, when the object instance is created). Constructor is a method object. Function in JavaScript can be used as a builder, it is not necessary to define a particular constructor method, a function can be called for each declared executed after the instantiation.

Constructor used to assign attributes to objects or to prepare for calling the function. In the latter category the method described herein may be added at the time of the definition, you may also be added before use.

In the following example, the time instance of the Person class constructor calls an alert function.

function Person() {
  alert('Person instantiated');
}

var person1 = new Person();
var person2 = new Person();

[Property (object attribute)]
property is contained in the variable class; each object instance in order to correct a number of inherited attributes, the attribute should be defined in the class prototype property (function).

You can use the keyword this to call class attributes, this is a reference to the current object. From external access (read / write) syntax whose properties are: InstanceName.Property; This is C ++, Java or many other languages ​​in the syntax is the same (in the class syntax this.Property commonly used to set and get property values)

In the following example, we define a Person class attribute for defining firstName and initial value at instantiation.

function Person(firstName) {
  this.firstName = firstName;
  alert('Person instantiated');
}

var person1 = new Person('Alice');
var person2 = new Person('Bob');

// Show the firstName properties of the objects
alert('person1 is ' + person1.firstName); // alerts "person1 is Alice"
alert('person2 is ' + person2.firstName); // alerts "person2 is Bob"

[Method (object attribute)]
method with properties very similar, except that: a is a function, may be defined as a function of the other. The method of accessing a call like property, except that the add () after the name of the method is likely to define a method with parameters, needs to assign a function to the prototype class attributes; This is the name assigned to the function used to objects used to call it on the outside.

In the following example, we give the Person class defines the methods sayHello (), and call it.

function Person(firstName) {
  this.firstName = firstName;
}

Person.prototype.sayHello = function() {
  alert("Hello, I'm " + this.firstName);
};

var person1 = new Person("Alice");
var person2 = new Person("Bob");

// call the Person sayHello method.
person1.sayHello(); // alerts "Hello, I'm Alice"
person2.sayHello(); // alerts "Hello, I'm Bob"

In JavaScript methods are usually bound to an object in a normal function, which means that the method can be called outside the context in which they are.

function Person(firstName) {
  this.firstName = firstName;
}

Person.prototype.sayHello = function() {
  alert("Hello, I'm " + this.firstName);
};

var person1 = new Person("Alice");
var person2 = new Person("Bob");
var helloFunction = person1.sayHello;

person1.sayHello();                                 // alerts "Hello, I'm Alice"
person2.sayHello();                                 // alerts "Hello, I'm Bob"
helloFunction();                                    // alerts "Hello, I'm undefined" (or fails
                                                    // with a TypeError in strict mode)
console.log(helloFunction === person1.sayHello);          // logs true
console.log(helloFunction === Person.prototype.sayHello); // logs true
helloFunction.call(person1);                        // logs "Hello, I'm Alice"

As illustrated, all reference point sayHello functions, including person1, Person.prototype, and helloFunction, are refer to the same function.

In the process of calling the function, the value of this depends on how we like to call a function in normal circumstances, we call the function by an expression person1.sayHello ():. To obtain the called function from a property object. At this time this function is set to acquire the object for us (ie person1). This is why person1.sayHello () uses the name "Alice" and person2.sayHello () uses the reason for "bob" in the name.

However, when we use a different method calls, this value is also different. When the variable helloFunction time () called in, this will be set to become a global object (ie window in the browser). Because the object (very possibly) no firstName property, we get the result is "Hello, I'm undefined". (This is the result in loose mode, in strict mode, the result will be different (this time will produce a error). but in order to avoid confusion, we are here not go into detail).

call and apply this change can be displayed

inherit

Create one or more classes of specialized version of the class is called inheritance (Javascript only supports single inheritance). Create a special version of the class is usually called subclasses, another type is often called the parent class. In Javascript, inherited and specialized subclasses instance be achieved by imparting a subclass of the parent class. In modern browsers you can use Object.create inheritance.

After the following example, we define a subclass of the class Person class Student as we redefine the sayHello () method and adds sayGoodBye () method.

// 定义Person构造器
function Person(firstName) {
  this.firstName = firstName;
}

// 在Person.prototype中加入方法
Person.prototype.walk = function(){
  alert("I am walking!");
};
Person.prototype.sayHello = function(){
  alert("Hello, I'm " + this.firstName);
};

// 定义Student构造器
function Student(firstName, subject) {
  // 调用父类构造器, 确保(使用Function#call)"this" 在调用过程中设置正确
  Person.call(this, firstName);

  // 初始化Student类特有属性
  this.subject = subject;
};

// 建立一个由Person.prototype继承而来的Student.prototype对象.
// 注意: 常见的错误是使用 "new Person()"来建立Student.prototype.
// 这样做的错误之处有很多, 最重要的一点是我们在实例化时
// 不能赋予Person类任何的FirstName参数
// 调用Person的正确位置如下,我们从Student中来调用它
Student.prototype = Object.create(Person.prototype); // See note below

// 设置"constructor" 属性指向Student
Student.prototype.constructor = Student;

// 更换"sayHello" 方法
Student.prototype.sayHello = function(){
  console.log("Hello, I'm " + this.firstName + ". I'm studying " + this.subject + ".");
};

// 加入"sayGoodBye" 方法
Student.prototype.sayGoodBye = function(){
  console.log("Goodbye!");
};

// 测试实例:
var student1 = new Student("Janet", "Applied Physics");
student1.sayHello();   // "Hello, I'm Janet. I'm studying Applied Physics."
student1.walk();       // "I am walking!"
student1.sayGoodBye(); // "Goodbye!"

// Check that instanceof works correctly
console.log(student1 instanceof Person);  // true
console.log(student1 instanceof Student); // true

For "Student.prototype = Object.create (Person.prototype); " this line, do not support the old method Object.create JavaScript engine,
you can use something like the following code to solve:

function createObject(proto) {
    function ctor() { }
    ctor.prototype = proto;
    return new ctor();
}

// Usage:
Student.prototype = createObject(Person.prototype);

Guess you like

Origin www.cnblogs.com/wangqingjiu/p/10966431.html