个人自学前端20-JS13-面向对象和继承实现,判断变量是否为数组或纯对象,伪数组
面向对象和继承实现
一 面向对象
面向对象是一种编程的思维,组织程序的一种方式。
面向对象三大特征:
1:封装
2:继承
3:多态 ( js无法实现多态,因为 js 函数没有重载功能 )
面向对象编程入门思路:
1:抽象出类。
抽象类的过程,需要思考,这个类的私有属性和公有方法都有什么。
如果有多个类,还需要实现继承等类之间的关系。
2:实例化。
通过抽象的类实例化对应个数的实例。
熟悉面向对象编程后,你会发现:
面向对象编写的程序几乎没有全局变量。
全局变量或者某些局部变量都变成了类的私有属性。
函数都变成了类的公有方法。
注意,面向对象抽象类的过程,是没有对和错的,只有好和坏。
面向对象编程,需要对 this 的指向问题非常清楚
二 创建自定义类
2.1:创建类。
js 的类都由函数充当。因此自定义类也需要通过一个普通函数来创建。
这个用于创建类的函数叫构造函数,习惯首字母大写。
创建类,需要定义类的私有属性和公有方法。
// 构造函数创建类的私有属性。
function Person(name){
this.name = name
}
// 类的原型创建公有方法。
Person.prototype.speak = function(){
console.log(this.name);
}
2.2:实例化
有了类之后,就可以通过类来实例化了。实例化需要通过操作符 New 修饰。
let oYm = new Person('幂幂');
// 访问私有属性.
console.log(oYm.name); // 幂幂
// 调用公有方法.
oYm.speak(); // 幂幂
2.3:new 做的事情
函数调用前有new:
1:让函数内的 this 指向类实例。
2:让类实例默认继承类的原型。
3:让构造函数返回类实例。
三 继承
js 的类继承,可以通过两方面完成。
1:如何继承私有属性。
2:如何继承公有方法。
3.1 继承私有属性
可以通过在子类中调用父类构造函数,并且通过call来改变this指向子类实例的方法来继承父类私有属性。
// 父类Person
function Person(name){
this.name = name
}
// 子类Student
function Student(number,name){
// 继承父类私有属性
Person.call(this,name);
this.num = number
}
3.2 继承公有方法
要继承父类的公有方法,必须让父类原型的公有方法出现在子类的原型链上.
或者让父类的原型对象出现在子类的原型链上.
可行的方法是: 让子类原型赋值为父类空实例.
// 父类Person
function Person(name){
this.name = name
}
// 子类Student
function Student(number,name){
// 继承父类私有属性
Person.call(this,name);
this.num = number
}
// 继续公有方法.子类实例继承子类原型,赋值后等同于继承父类实例,
Student.prototype = new Person();
这个做法可行,但是需要额外调用一次父类构造函数。不太好。
// 通过这个方法,可以让子类原型默认继承父类原型。
Student.prototype = Object.create(Person.prototype);
面试常问 js 的继承问题,可以通过这两方面回调。
同时继承私有属性和公有方法的继承方式称之为混合继承。派生的方法有寄生继承。
3.3 一些检测方法
访问对象的上一级原型对象:
对象.__proto__
Object.getPrototypeOf(对象)
修改对象的上一级原型对象:
对象.__proto__ = 新的对象
Object.setPrototypeOf(对象,新的对象)
检测对象是否具有某个属性.
对象.hasOwnProperty(属性)
检测属性是否存在于对象的原型链上
属性 in 对象
检测A对象是否存在于B对象的原型链上.
A对象.isPrototypeOf(B对象)
检测类的原型是否存在于对象的原型链上
对象 instanceof 类
instanceof 和 isPrototypeOf的区别
instanceof检测类的原型对象在不在原型链上
isPrototypeOf检测任意的对象在不在原型链上.
四 其他
4.1 数组的方法
实例方法
push,pop,shift,unshift,reverse,sort,splice
concat,slice,includes,indexOf,join
forEach,map,filter,some,every,reduce,find,findIndex
静态方法
Array.isArray => 判断是不是数组.
Array.from => 把伪数组转换为真正的数组.
Array.of => 代替数组的构造函数.
4.2 如何判断一个变量是不是数组?
1.不能用typeof,因为typeof得到的结果是object
2.用Array.isArray在IE8不支持.
3.intanceof 也不一定准确.
let arr = [];
// let flag1 = isArray(arr);
// let flag2 = isPlainObject({});
// 封装一个函数用于判断一个变量是不是数组.
function isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]'
}
// 100%正确的答案
// if (Object.prototype.toString.call(arr) === '[object Array]') {
// alert('是数组')
// } else {
// alert('不是数组')
// }
4.3 如何判断一个变量是不是纯对象?
不能用typeof,为数组,null和纯对象的typeof结果都是object.
// 封装一个函数用于判断一个变量是不是纯对象.
function isPlainObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]'
}
4.4 伪数组
let aDiv = document.querySelectorAll('div');
// aDiv不是数组实例,因此不能用数组的方法。
// 但是aDiv可以使用下标,可以有length属性表示元素个数.
// aDiv是一种伪数组.可以有下标,可以有length.但是就是不能访问数组的方法.
// 所有的标签数组都是伪数组.
// arguments也是一种伪数组.(ES6的rest参数是一个真正的数组).
// fileList也是一个伪数组.
console.log(Array.isArray(aDiv));
console.log(aDiv instanceof Array);
console.log(Array.prototype.isPrototypeOf (aDiv));
console.log(Object.prototype.toString.call(aDiv) === '[object Array]');
function fn(...rest) {
console.log(Array.isArray(rest));// true
console.log(Array.isArray(arguments));// false
}
fn();
本文来自博客园,作者:暗鸦08,转载请注明原文链接:https://www.cnblogs.com/DarkCrow/p/15083582.html

浙公网安备 33010602011771号