Javascipt syntax does not support "class" (class) [already supported by es6], but there are methods to simulate classes. Today I will mainly talk about the method of simulating "classes" in Javascipt and the summary and review of inheritance in js.
js中实现“类”与继承,既是重点,又是难点。很多同学可能都对js中“类”与继承都有所了解,但是深入剖析的时候,感觉力不从心、模棱两可。
Let’s first summarize several methods for defining “classes” by js:
Method 1: Constructor method
This method is a relatively classic method and we will see it often. When generating an instance, use the new keyword. The properties and methods of the class can also be defined on the constructor's prototype object.
function Person(name,age,job){ this.name=name; this.age=age; this.job=job;}Person.prototype.sayName=function(){ alert(this.name);}var person1 = new Person("Zhang San","29","web frontpage manager");var person2 = new Person("Li Si","22","doctor");person1.sayName(); //Pop "Zhang San" console.log(person2.name)//Output "Li Si"Method 2: Object.create() method
The method Object.creat() as an alternative to the new operator is only released after ES5. Using this method, a "class" is an object, not a function.
var myMammal = { name : 'Herb the Mammal', get_name : function () { return this.name; }, says : function () { return this.saying || ''; }}var myCat = Object.create(myMammal);myCat.name = 'Henrietta';myCat.saying = 'meow';myCat.get_name = function () { console.log(this.says + ' ' + this.name + this.says);}myCat.get_name();Output:
function () { return this.saying || ''; } Henriettafunction () { return this.saying || ''; }目前,各大浏览器的最新版本(包括IE9)都部署了这个方法。如果遇到老式浏览器,可以用下面的代码自行部署。
if (!Object.create) { Object.create = function (o) { function F() {} F.prototype = o; return new F(); }; }Method 3: Minimalist law
Package
This method does not use this and prototype, and the code is very simple to deploy. First of all, it also uses an object to simulate "class". In this class, define a constructor creatFn() to generate an instance.
var Dog= { creatFn: function(){ // some code here } };Then, in creatFn(), define an instance object and use this instance object as the return value.
var Dog= { creatFn: function(){ var dog= {}; dog.name = "狗狗"; dog.makeSound = function(){ alert("汪汪汪"); }; return dog; } };使用的时候,调用creatFn()方法,就可以得到实例对象。
var dog1 = Dog.creatFn(); dog1.makeSound(); // Woof
这种方法的好处是,容易理解,结构清晰优雅,符合传统的"面向对象编程"的构造,因此可以方便地部署下面的特性。
inherit
让一个类继承另一个类,实现起来很方便。 Just call the creatFn() method of the latter in the creatFn() method. First define an Animal class.
var Animal = { creatFn: function(){ var animal = {}; animal.eat= function(){ alert("吃饭饭"); }; return animal; } };然后,在Dog的creatFn()方法中,调用Animal的creatFn()方法。
var Dog= { creatFn: function(){ var dog= Animal.creatFn(); dog.name = "Dog"; dog.makeSound = function(){ alert("Wangwoo"); }; return dog; } };The Dog instance obtained in this way will inherit the Dog class and the Animal class at the same time.
var dog1= Dog.creatFn(); dog1.eat(); // 吃饭饭
Private properties and private methods
In the creatFn() method, as long as the methods and properties that are not defined on the dog object are private.
var Dog= { creatFn: function(){ var dog= {}; var sound = "汪汪汪"; dog.makeSound = function(){ alert(sound); }; return dog; } };The internal variable sound in the above example cannot be read externally, and can only be read through the public method makeSound() of dog.
var dog1 = Dog.creatFn(); alert(dog1.sound); // undefined
Data Sharing
有时候,我们需要所有实例对象,能够读写同一项内部数据。 At this time, just encapsulate this internal data inside the class object and outside the creatFn() method.
var Dog= { sound : "Wowangwoo", creatFn: function(){ var dog= {}; dog.makeSound = function(){ alert(Dog.sound); }; dog.changeSound = function(x){ Dog.sound = x; }; return dog; } };然后,生成两个实例对象:
var dog1 = Dog.creatFn(); var dog2 = Dog.creatFn(); dog1.makeSound(); // Woof
At this time, if there is an instance object and the shared data is modified, the other instance object will also be affected.
dog2.changeSound("Wuwuwu"); dog1.makeSound(); //Wuwuwuwujs inheritance
关于继承,网上也有很多资料可以查询,但是很多朋友对其理解的不够深入。 When it comes to inheritance, if you don’t check the information and suddenly you may not be able to tell the reason.这就说明我们的基础知识打的不够扎实。 Not thoroughly understood. Today, I stand on the basis of my predecessors, and let’s review this inheritance with you.
继承最常用的两种方式如下:
Prototype chain inheritance
What is prototype chain inheritance?这里我就不说什么定义了。其实就是用prototype继承父级。
For example:
function Parent(){ this.name = 'mike';} function Child(){ this.age = 12;}Child.prototype = new Parent();//Child inherits Parent and forms a chain through the prototype var test = new Child();alert(test.age);alert(test.name);//Get inherited attributes//Continue the prototype chain inheritance function Brother(){ //Brother constructs this.weight = 60;}Brother.prototype = new Child();//Continue the prototype chain inherits var brother = new Brother();alert(brother.name);//继承了Parent和Child,弹出mikealert(brother.age);//弹出12上面例子,通过原型,形成链条,Child继承了Parent,Brother有继承了Child,最后brother既有Child和Parent的属性,又有自己的属性。 This is the inheritance of the original chain.
Classical inheritance (borrow constructor)
Classical inheritance generally uses call or apply to call the supertype constructor internally. For example:
function Parent(age){ this.name = ['mike','jack','smith']; this.age = age;}function Child(age){ Parent.call(this,age);}var test = new Child(21);alert(test.age);//21alert(test.name);//mike,jack,smithtest.name.push('bill');alert(test.name);//mike,jack,smith,billThe above two inheritances are the most basic two inheritance methods.
此外还有一些继承方式,我们一起来看一下!
Combination inheritance
组合继承通常是上面两种继承方式组合在一起使用的继承方式。
As an example:
function Parent(age){ this.name = ['mike','jack','smith']; this.age = age;}Parent.prototype.run = function () { return this.name + ' are both' + this.age;};function Child(age){ Parent.call(this,age);//Object impersonation, pass arguments to supertype}Child.prototype = new Parent();//Prototype chain inheritance var test = new Child(21);//Write new Parent(21) also OK to alert(test.run());//mike,jack,smith are both21Prototype inheritance
It is only one word different from the original chain inheritance mentioned above, but it is not the same content.我们所说的原型式继承,就是我们上节课所讲的,通过Object.create()方式来创建新的类。因为这种方式老式浏览器不支持。 Therefore, if we do not use Object.create(), there can also be an alternative method, as follows:
function obj(o){ function F(){} F.prototype = o; return new F(); }这个函数,就实现了我们Object.create()创建类的方式!
Therefore, the following is:
function obj(o){ function F(){} F.prototype = o; return new F(); }var box = { name : 'trigkit4', arr : ['brother','sister','baba']};var b1 = obj(box);alert(b1.name);//trigkit4b1.name = 'mike';alert(b1.name);//mikealert(b1.arr);//brother,sister,babab1.arr.push('parents');alert(b1.arr);//brother,sister,baba,parentsvar b2 = obj(box);alert(b2.name);//trigkit4alert(b2.arr);//brother,sister,baba,parentsParasitic inheritance
As an example:
function creatAnother(original){ var clone=new Object(original); clone.sayHi=function(){ alert("hi") }; return clone;}var person={ name:"haorooms", friends:["hao123","zhansan","lisi"]}var anotherPerson=creatAnother(person); antherPerson.sayHi();//hi寄生组合式
function inheritPrototype (subType,superType) { var prototype = Object.creat(superType.prototype); prototype.constructor = subType; subType.prototype = prototype;};function SuperType (name) { this.name = name; this.colors = ['red', 'blue', 'green'];}SuperType.prototype.sayName = function () { console.log(this.name);}function SubType(name, age) { //InheritPrototype.call(this,name); this.age = age;}//InheritPrototype(SubType,SuperType);SubType.prototype.sayAge = function () { console.log(this.age);}var instance = new SubType();类的继承,基本上就是如上几种方式。下面再简单的说一下ES6的class类吧!
es6 implementation class
//Define class class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '('+this.x+', '+this.y+')'; }}var point = new Point(2, 3);point.toString() // (2, 3)point.hasOwnProperty('x') // truepoint.hasOwnProperty('y') // truepoint.hasOwnProperty('toString') // falsepoint.__proto__.hasOwnProperty('toString') // trueClass's inheritance
class ColorPoint extends Point { constructor(x, y, color) { super(x, y); // Call the constructor(x, y) of the parent class this.color = color; } toString() { return this.color + ' ' + super.toString(); // Call the toString() of the parent class }}