Home > Web Front-end > JS Tutorial > body text

Detailed explanation of JavaScript inheritance (2)_js object-oriented

WBOY
Release: 2016-05-16 18:50:04
Original
881 people have browsed it

this

This represents the current object. If this is used in the global scope, it refers to the current page object window; if this is used in a function, what this refers to is based on the object on which this function is called at runtime. We can also use the two global methods apply and call to change the specific pointer of this in the function.

Let’s first look at an example of using this in the global scope:

  <script type="text/javascript">
   console.log(this === window); // true
   console.log(window.alert === this.alert); // true
   console.log(this.parseInt("021", 10)); // 10
  </script>
  
Copy after login

This in the function is determined at runtime, not when the function is defined, as follows:

  // 定义一个全局函数
  function foo() {
   console.log(this.fruit);
  }
  // 定义一个全局变量,等价于window.fruit = "apple";
  var fruit = "apple";
  // 此时函数foo中this指向window对象
  // 这种调用方式和window.foo();是完全等价的
  foo(); // "apple"

  // 自定义一个对象,并将此对象的属性foo指向全局函数foo
  var pack = {
   fruit: "orange",
   foo: foo
  };
  // 此时函数foo中this指向window.pack对象
  pack.foo(); // "orange"
  
Copy after login

The global functions apply and call can be used to change the pointer of this in the function, as follows:

  // 定义一个全局函数
  function foo() {
   console.log(this.fruit);
  }
  
  // 定义一个全局变量
  var fruit = "apple";
  // 自定义一个对象
  var pack = {
   fruit: "orange"
  };
  
  // 等价于window.foo();
  foo.apply(window); // "apple"
  // 此时foo中的this === pack
  foo.apply(pack); // "orange"
  
Copy after login
Note: The two functions apply and call have the same function. The only difference is that the parameter definitions of the two functions are different.

Because functions are also objects in JavaScript, we can see the following interesting examples:

  // 定义一个全局函数
  function foo() {
   if (this === window) {
    console.log("this is window.");
   }
  }
  
  // 函数foo也是对象,所以可以定义foo的属性boo为一个函数
  foo.boo = function() {
   if (this === foo) {
    console.log("this is foo.");
   } else if (this === window) {
    console.log("this is window.");
   }
  };
  // 等价于window.foo();
  foo(); // this is window.
  
  // 可以看到函数中this的指向调用函数的对象
  foo.boo(); // this is foo.
  
  // 使用apply改变函数中this的指向
  foo.boo.apply(window); // this is window.
  
Copy after login

prototype

We have already used prototypes to simulate the implementation of classes and inheritance in Chapter 1. Prototype is essentially a JavaScript object. And every function has a default prototype attribute.
If this function is used in the scenario of creating a custom object, we call this function a constructor. For example, the following is a simple scenario:

  // 构造函数
  function Person(name) {
   this.name = name;
  }
  // 定义Person的原型,原型中的属性可以被自定义对象引用
  Person.prototype = {
   getName: function() {
    return this.name;
   }
  }
  var zhang = new Person("ZhangSan");
  console.log(zhang.getName()); // "ZhangSan"
  
Copy after login
As an analogy, let’s consider the data types in JavaScript - String, Number, Array, Object, Date. wait. We have reason to believe that these types are implemented as constructors in JavaScript, such as:
  // 定义数组的构造函数,作为JavaScript的一种预定义类型
  function Array() {
   // ...
  }
  
  // 初始化数组的实例
  var arr1 = new Array(1, 56, 34, 12);
  // 但是,我们更倾向于如下的语法定义:
  var arr2 = [1, 56, 34, 12];
  
Copy after login
At the same time, many methods of operating on arrays (such as concat, join, push) should also be defined in the prototype attribute.
In fact, all intrinsic data types of JavaScript have read-only prototype attributes (this is understandable: if the prototype attributes of these types are modified, the predefined methods disappear), but we can Add your own extension methods to it.
  // 向JavaScript固有类型Array扩展一个获取最小值的方法
  Array.prototype.min = function() {
   var min = this[0];
   for (var i = 1; i < this.length; i++) {
    if (this[i] < min) {
     min = this[i];
    }
   }
   return min;
  };
  
  // 在任意Array的实例上调用min方法
  console.log([1, 56, 34, 12].min()); // 1
  
Copy after login

Note: There is a trap here. After adding an extension method to the prototype of Array, this extension method will also be looped out when using for-in to loop the array.
The following code illustrates this (assuming that the min method has been extended to the Array prototype):
  var arr = [1, 56, 34, 12];
  var total = 0;
  for (var i in arr) {
   total += parseInt(arr[i], 10);
  }
  console.log(total); // NaN
  
  
Copy after login
The solution is also very simple:
  var arr = [1, 56, 34, 12];
  var total = 0;
  for (var i in arr) {
   if (arr.hasOwnProperty(i)) {
    total += parseInt(arr[i], 10);
   }
  }
  console.log(total); // 103
  
Copy after login

constructor

constructor always points to the constructor that created the current object. For example:

  // 等价于 var foo = new Array(1, 56, 34, 12);
  var arr = [1, 56, 34, 12];
  console.log(arr.constructor === Array); // true
  // 等价于 var foo = new Function();
  var Foo = function() { };
  console.log(Foo.constructor === Function); // true
  // 由构造函数实例化一个obj对象
  var obj = new Foo();
  console.log(obj.constructor === Foo); // true
  
  // 将上面两段代码合起来,就得到下面的结论
  console.log(obj.constructor.constructor === Function); // true
  
Copy after login

But when the constructor encounters the prototype, something interesting happens.
We know that each function has a default attribute prototype, and the constructor of this prototype points to this function by default. As shown in the following example:

  function Person(name) {
   this.name = name;
  };
  Person.prototype.getName = function() {
   return this.name;
  };
  var p = new Person("ZhangSan");
  
  console.log(p.constructor === Person); // true
  console.log(Person.prototype.constructor === Person); // true
  // 将上两行代码合并就得到如下结果
  console.log(p.constructor.prototype.constructor === Person); // true
  
Copy after login
When we redefined the prototype of the function (note: the difference from the above example, this is not a modification but an override), the behavior of the constructor was a bit strange, as shown in the following example:
  function Person(name) {
   this.name = name;
  };
  Person.prototype = {
   getName: function() {
    return this.name;
   }
  };
  var p = new Person("ZhangSan");
  console.log(p.constructor === Person); // false
  console.log(Person.prototype.constructor === Person); // false
  console.log(p.constructor.prototype.constructor === Person); // false
  
Copy after login
Why?
It turns out that when overwriting Person.prototype, it is equivalent to the following code operation:
  Person.prototype = new Object({
   getName: function() {
    return this.name;
   }
  });
  
Copy after login
And the constructor always points to the constructor that creates itself, so at this time Person.prototype.constructor === Object, that is:
  function Person(name) {
   this.name = name;
  };
  Person.prototype = {
   getName: function() {
    return this.name;
   }
  };
  var p = new Person("ZhangSan");
  console.log(p.constructor === Object); // true
  console.log(Person.prototype.constructor === Object); // true
  console.log(p.constructor.prototype.constructor === Object); // true
  
Copy after login
How to fix this problem? The method is also very simple, just override Person.prototype.constructor:
  function Person(name) {
   this.name = name;
  };
  Person.prototype = new Object({
   getName: function() {
    return this.name;
   }
  });
  Person.prototype.constructor = Person;
  var p = new Person("ZhangSan");
  console.log(p.constructor === Person); // true
  console.log(Person.prototype.constructor === Person); // true
  console.log(p.constructor.prototype.constructor === Person); // true
  
Copy after login


In the next chapter we will improve the implementation of the Person-Employee class and inheritance mentioned in the first chapter.

Related labels:
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!