一、题目
- 如何准确判断一个变量是不是数组?
- 手写一个简易的jQuery,考虑插件和扩展性?
- class的原型本质,如何理解?
二、知识点
1.class和继承
1.1class
- constructor
- 属性
- 方法
创建一个学生类Student
,构造方法里有姓名name
和学号number
这两个属性,还有sayHi()
这个方法。
使用new
关键字创建出xialuo和madongmei这两个学生实例。
// 类
class Student {
constructor(name, number) {
this.name = name;
this.number = number;
}
sayHi() {
console.log(`姓名--${this.name}, 学号--${this.number}`);
}
}
// 通过new关键字来创建类的实例/对象
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name)
console.log(xialuo.number)
xialuo.sayHi()
console.log('----------')
const madongmei = new Student('马冬梅', 100)
console.log(madongmei.name)
console.log(madongmei.number)
xialuo.sayHi()
打印结果:
1.2继承
- extends
- super
- 扩展或重写方法
定义了People
类,Student
类和Teacher
类通过extends
继承自People
类。
// 父类
class People {
constructor(name) {
this.name = name
}
eat() {
console.log(`${this.name} eat something`);
}
}
// 子类
class Student extends People {
constructor(name, number) {
super(name)
this.number = number
}
sayHi() {
console.log(`姓名--${this.name}, 学号--${this.number}`);
}
}
// 子类
class Teacher extends People {
constructor(name, najor) {
super(name)
this.major = najor
}
teach() {
console.log(`${this.name} 教授 ${this.major}`);
}
}
// 实例
const xialuo = new Student('夏洛', 100)
console.log(xialuo.name);
console.log(xialuo.number);
xialuo.sayHi()
xialuo.eat()
console.log('------------')
const wanglaoshi = new Teacher('王老师', '语文')
console.log(wanglaoshi.name)
console.log(wanglaoshi.major)
wanglaoshi.teach()
wanglaoshi.eat()
运行结果:
2.类型判断instanceof
xialuo instanceof Student // true
xialuo instanceof People // true
xialuo instanceof Object // true
[] instanceof Array // true
[] instanceof Object // true
{} instanceof Object // true
3.原型和原型链
3.1原型
// class 实际上是函数,可见是语法糖
typeof People // 'function'
typeof Student // 'function'
// 隐式原型和显式原型
console.log(xialuo.__proto__)
console.log(Student.prototype)
console.log(xialuo.__proto__ === Student.prototype)
打印结果:
原型关系:
- 每个
class
都有显式原型prototype
- 每个实例都有隐式原型
__proto__
- 实例的隐式原型
__proto__
指向对应class
的显式原型prototype
基于原型的执行规则
- 获取属性
xialuo.name
或执行方法xialuo.sayHi()
时 - 先在自身属性和方法寻找
- 如果找不到则自动去
__proto__
中查找
3.2原型链
console.log(Student.prototype.__proto__)
console.log(People.prototype)
console.log(Student.prototype.__proto__ === People.prototype)
打印结果:
重要提示!!!
class
是ES6
语法规范,由ECMA
委员会发布ECMA
只规定语法规则,即我们代码的书写规范,不规定如何实现- 以上实现方式都是
V8
引擎的实现方式,也是主流的
三、解答
- 如何准确判断一个变量是不是数组?
a instanceof Array
- 手写一个简易的jQuery,考虑插件和扩展性?
class jQuery {
constructor(selector) {
const result = document.querySelectorAll(selector)
const length = result.length
for (let i = 0; i < length; i++) {
this[i] = result[i]
}
this.length = length
this.selector = selector
}
get(index) {
return this[index]
}
each(fn) {
for (let i = 0; i < this.length; i++) {
const elem = this[i]
fn(elem)
}
}
on(type, fn) {
return this.each(elem => {
elem.addEventListener(type, fn, false)
})
}
// 扩展更多DOM API
}
// 插件
jQuery.prototype.dialog=function(info){
alert(info)
}
// 造轮子
class myJQuery extends jQuery{
constructor(selector){
super(selector)
}
// 扩展自己的方法
addClass(className){
// ...
}
style(data){
}
}
控制台打印结果:
- class的原型本质,如何理解?
参考原型和原型链的图示;
属性和方法的执行规则。
小结
- class和继承,结合上面手写jQuery的示例来理解
- instanceof
- 原型和原型链:图示&执行规则