本文主要讲解“如何掌握前端JavaScript中的类”,感兴趣的朋友不妨看看。本文介绍的方法简单、快速、实用。让边肖带你学习“如何用前端JavaScript掌握这门课”!
00-1010类是创建对象的模板。javaScript中生成对象实例的方法是通过构造函数,这与主流的面向对象语言(Java、C#)有很大的不同。
功能点(x,y){ 0
this.x=x
this.y=y
}
point . prototype . tostring=function(){ 0
return'(' this.x ',' this . y ')';
};
varp=newPoint(1,1);ES6提供了一种更接近Java语言的编写方法,并引入了Class的概念作为对象的模板。使用class关键字,您可以定义类。
如下:
classPoint{
构造函数(x,y){ 0
this.x=x
this.y=y
}
toString(){ 0
return'(' this.x ',' this . y ')';
}
}如下:constructor()是构造方法,而this代表实例对象:
//ES5函数声明。
functionPoint(){ 0
//.
}
//ES6类声明。
classPoint{
//.
构造函数(){ 0
}
}
typeofPoint//'函数'
point====Point.prototype . constructor//true类中定义的方法是紧紧抓住point . prototype,所以类只提供语法糖,本质是原型链调用。
classPoint{
构造函数(x,y){ 0
this.x=x
this.y=y
}
toString(){ 0
return'(' this.x ',' this . y ')';
}
}
point . prototype={ 0
//.
toString()
}
varp=newPoint(1,1);
p.toString()//(1,1)类的数据类型就是函数,它本身就是指向函数的构造函数:
//未命名/匿名类。
letPoint=cla
ss {
constructor(x, y) {
this.x = x;
this.y = y;
}
};
Point.name // Point
函数声明和类声明有个重要区别,函数声明会提升,类声明不会提升。
> let p = new Point(); // 被提升不会报错 > function Point() {} > > let p = new Point(); // 报错,ReferenceError > class Point {} >
1.1 constructor()
constructor()
方法是类的默认方法,new
生成实例对象时会自动调用该方法。
一个类必须有constructor()
方法,如果没有显式定义,引擎会默认添加一个空的constructor()
。
constructor()
方法默认返回实例对象(即this
)。
class Point { } // 自动添加 class Point { constructor() {} }
1.2 getter和setter
与 ES5
一样,在类的内部可以使用get
和set
关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。
class User { constructor(name) { this.name = name; } get name() { return this.name; } set name(value) { this.name = value; } }
1.3 this
类的方法内部的this
,它默认指向类的实例,在调用存在this的方法时,需要使用 obj.method()
方式,否则会报错。
class User { constructor(name) { this.name = name; } printName(){ console.log('Name is ' + this.name) } } const user = new User('jack') user.printName() // Name is jack const { printName } = user; printName() // 报错 Cannot read properties of undefined (reading 'name')
如果要单独调用又不报错,一种方法可以在构造方法里调用bind(this)
。
class User { constructor(name) { this.name = name; this.printName = this.printName.bind(this); } printName(){ console.log('Name is ' + this.name) } } const user = new User('jack') const { printName } = user; printName() // Name is jack
bind(this)
会创建一个新函数,并将传入的this作为该函数在调用时上下文指向。
另外可以使用箭头函数,因为箭头函数内部的this总是指向定义时所在的对象。
class User { constructor(name) { this.name = name; } printName = () => { console.log('Name is ' + this.name) } } const user = new User('jack') const { printName } = user; printName() // Name is jack
1.4 静态属性
静态属性指的是类本身的属性,而不是定义在实例对象this
上的属性。
class User { } User.prop = 1; User.prop // 1
1.5 静态方法
可以在类里面定义静态方法,该方法不会被对象实例继承,而是直接通过类来调用。
静态方法里使用this
是指向类。
class Utils { static printInfo() { this.info(); } static info() { console.log('hello'); } } Utils.printInfo() // hello
关于方法的调用范围限制,比如:私有公有,ES6
暂时没有提供,一般是通过约定,比如:在方法前面加下划线_print()表示私有方法。
2、继承
Java
中通过extends
实现类的继承。ES6
中类也可以通过extends
实现继承。
继承时,子类必须在constructor
方法中调用super
方法,否则新建实例时会报错。
class Point3D extends Point { constructor(x, y, z) { super(x, y); // 调用父类的constructor(x, y) this.z = z; } toString() { return super.toString() + ' ' + this.z ; // 调用父类的toString() } }
父类的静态方法,也会被子类继承
class Parent { static info() { console.log('hello world'); } } class Child extends Parent { } Child.info() // hello world
2.1 super关键字
在子类的构造函数必须执行一次super
函数,它代表了父类的构造函数。
class Parent {} class Child extends Parent { constructor() { super(); } }
在子类普通方法中通过super
调用父类的方法时,方法内部的this
指向当前的子类实例。
class Parent { constructor() { this.x = 1; this.y = 10 } printParent() { console.log(this.y); } print() { console.log(this.x); } } class Child extends Parent { constructor() { super(); this.x = 2; } m() { super.print(); } } let c = new Child(); c.printParent() // 10 c.m() // 2
2.2 _proto_和prototype
初学JavaScript
时, _proto_
和prototype
很容易混淆。首先我们知道每个JS
对象都会对应一个原型对象,并从原型对象继承属性和方法。
-
prototype
一些内置对象和函数的属性,它是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。 -
_proto_
每个对象都有这个属性,一般指向对应的构造函数的prototype
属性。
下图是一些拥有prototype内置对象:
根据上面描述,看下面代码
var obj = {} // 等同于 var obj = new Object() // obj.__proto__指向Object构造函数的prototype obj.__proto__ === Object.prototype // true // obj.toString 调用方法从Object.prototype继承 obj.toString === obj.__proto__.toString // true // 数组 var arr = [] arr.__proto__ === Array.prototype // true
对于function
对象,声明的每个function
同时拥有prototype
和__proto__
属性,创建的对象属性__proto__
指向函数prototype
,函数的__proto__
又指向内置函数对象(Function)的prototype
。
function Foo(){} var f = new Foo(); f.__proto__ === Foo.prototype // true Foo.__proto__ === Function.prototype // true
2.3 继承中的__proto__
类作为构造函数的语法糖,也会同时有prototype
属性和__proto__
属性,因此同时存在两条继承链。
-
子类的
__proto__
属性,表示构造函数的继承,总是指向父类。 -
子类prototype属性的
__proto__
属性,表示方法的继承,总是指向父类的prototype
属性。
class Parent { } class Child extends Parent { } Child.__proto__ === Parent // true Child.prototype.__proto__ === Parent.prototype // true
2.4 继承实例中的__proto__
子类实例的__proto__
属性,指向子类构造方法的prototype
。
子类实例的__proto__
属性的__proto__
属性,指向父类实例的__proto__
属性。也就是说,子类的原型的原型,是父类的原型。
class Parent { } class Child extends Parent { } var p = new Parent(); var c = new Child(); c.__proto__ === p.__proto__ // false c.__proto__ === Child.prototype // true c.__proto__.__proto__ === p.__proto__ // true
到此,相信大家对“如何掌握前端JavaScript中的class类”有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/41725.html