1、原型链继承
众所周知,JavaScript不是一种传统的面向对象的语言,因为他跟传统的面向对象语言不同,它没有类于php或者java等传统编程语言的类。那么,它是如何实现面向对象的功能的呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function Cat(name,age){ this.name = name; this.age = age; }
Cat.prototype.type = '猫科动物'; Cat.prototype.eat = function(){alert('吃');}
var cat1 = new Cat("大毛","23"); alert(cat1.type);
|
上面的这种,我们叫他原型链继承。JavaScript规定,所有的构造函数,都有Prototype属性,指向另一个对象,这个对象所有的属性和方法,都会被另一个实例对象继承。
2、类语法实现继承
原型链的语法,在于理解起来困难,不如Java等的面向对象理解起来直观。因此,ES6标准推出了一个class的语法糖,让我们也可以像其他面向对象语言一样,实现简单的类继承。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Bar { default(x,y) { console.log(x,y); } default2(i,u) { console.log(i,u); } }
var b = new Bar();
b.default(5,6); b.default2(7,8);
|
因为ES6的class语法实质上,只是一种语法糖,所以尽管写法上有区别,但实现上,还是原型链继承。
1 2 3 4 5 6 7 8 9 10 11
| class default { default(x,y) { console.log(x,y) } }
default.prototype = { default(x,y){} }
|
再来看一个例子,这里,我们要做一件事。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| const ClassMe = class me { getClassName(){ return Me.name; } }
let Me = new ClassMe();
inst.getClassMe();
const ClassMe = class {}
let person = new class { constructor(name) { this.name = name; } sayName() { console.log(this.name) } },('吴万海');
person.sayName();
|
不存在的变量提升
我们在编写JavaScript函数中,肯定有写法利用到JavaScript的变量提升。比如把大串的函数封装放到函数执行的最下面。但是在class中是不允许这样做的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| add();
function add() { console.log('123'); }
new Foo(); class Foo {};
{ let Foo = class {}; class Bar expends Foo { } }
|
class的静态方法
类相当于实例的原型,所有在类中定义的方法,都会在实例中继承。如果在一个方法前,假如static关键字,就表示这个方法不会被继承,而是直接通过类来调用这就是静态方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Foo { static classMethod() { return 'hello' } Foo.classMethod(); }
var foo = new Foo(); foo.classMethod;
|
上面的程序报了一个错,表示不存在这个函数方法。因为我们这里使用了static关键字,可以直接在类上调用,而不是在实例上。
待续….
JavaScript的类语法,让我们编写面向对象的程序更简单。因此,条件支持,应该更多的使用新语法。
3、箭头函数
箭头函数,本质上是匿名函数。只是在形式上做了简化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
function add(x,y) { console.log(x,y); }
add(4,5);
var add = (x,y)=>x*y
等同于
function(x,y) { return x*y }
|
这种因为结构简单,所以,我们省略了,大括号和renturn关键字,但是,如果更复杂一点的,就不行了。
1 2 3 4 5 6 7 8
| (x,y) => { if (x > 0) { return x*x } else { return x*y } }
|