JavaScript的原型与继承

原型

  • 原型 prototype,我们所创建的每一个实例,解析器都会向这个函数中添加一个prototype,属性,这个属性会对应这个一个对象,这个对象就是原型对象(显式原型),原型对象就相当于一个公共的区域,当前实例都可以访问到这个原型对象

示例:

js 复制代码
Person.prototype.sayName = function () {
    console.log(this.name)
}
Person.prototype.xxx ='这是一个属性'
let p1 = new Person('张三',20,'男');
let p2 = new Person('李四',20,'男');
console.log(p1)
console.log(p2)
  • 如果函数作为普通的函数调用,那么prototype没有任何作用,当前函数以构造函数的方式调用时,它所创建的对象会隐含一个属性,指向该构造函数的原型对象
  • 我们可以通过proto(隐式原型),来访问到该属性
  • 当我们访问一个对象的属性或者方法时,会先在自身寻找(比如访问p1 对象的name属性)如果找不到则去原型对象中寻找,找到了直接使用
js 复制代码
console.log(p2.xxx);
//hasOwnProperty 判断这个属性是否是 p2特有的
console.log(p2.hasOwnProperty('xxx'))
//__proto__.hasOwnProperty('xxx') 判断这个属性是否共有的
console.log(p2.__proto__.hasOwnProperty('xxx'))

继承

原型链继承

js 复制代码
//定义父类构造函数
function SupperType(){
    this.subProp = '这是父类的一条消息';
    this.fuxxx = '这是父类的一条消息-测试';
}
//给父类的原型添加方法
SupperType.prototype.showSupperProp = function (){
    console.log("SupperType:",this.subProp,this.fuxxx)
}
//定义子类的构造函数
function  SubType(){
    this.subProp = '这是子类的一条消息';
}
//将子类的原型 指向父类实例
SubType.prototype = new SupperType();

//在子类的原型上添加方法
SubType.prototype.showSubProp = function (){
    console.log("SubType: ",this.subProp);
}

//将设置子类的原型构造函数为子类本身
SubType.prototype.constructor = SubType;
//创建子类实例  完成继承
var subType = new SubType();
//调用子类的方法
subType.showSubProp();
//调用父类方法
subType.showSupperProp();

console.log(subType.toString());
console.log(SubType.prototype.constructor)

原型链继承的特点:

  1. 原型链继承多个实例的引用类型属性指向相同一个实例被修改了原型属性,另一个实例的原型属性也会被影响
  2. 不能传递参数
  3. 继承单一

构造继承

js 复制代码
//创建父类构造
function SupperType(name){
    this.name = name;
    this.showSupperName = function (){
        console.log("SupperType: ",this.name)
    }
}

//创建子类构造
function SubType(name,age){
    //在子类中 继承父类 调用call方法 继承所有的属性与方法
    SupperType.call(this,name);
    this.age = age;
}

//给子类原型  定义方法
SubType.prototype.showSubName = function (){
    console.log("SubType: ",this.name,this.age)
}

let zzh = new SubType('渣渣辉',65);
zzh.showSupperName();
zzh.showSubName();
console.log(zzh);

构造继承的特点:

  1. 只能继承父类实例的属性和方法,不能继承原型属性和方法
  2. 无法实现构造函数的复用,每个子类都有父类的实例的函数副本
  3. 比较臃肿 ,影响性能

组合继承

组合继承就是将原型链继承和构造继承结合在一起

js 复制代码
function Person(name,age){
    this.name = name;
    this.age = age;
}
Person.prototype.setName = function (name) {
    this.name = name;
}
function Student(name,age,sex) {
    //------------构造继承-----
    Person.call(this,name,age);
    this.sex = sex;
}
// 原型链继承
Student.prototype = new Person();

Student.prototype.constructor = Student;

Student.prototype.setSex = function (sex) {
    this.sex = sex;
}

let s = new Student('李四',25,'男');
console.log(s.name,s.age,s.sex);
s.setName('王五');
s.setSex("女");
console.log(s.name,s.age,s.sex);
console.log(s);

特点:

  1. 父类中的实例属性和方法,在子类的实例中存在
  2. 也在子类的原型中存在,栈内存

数组

创建数组:

js 复制代码
var arr = new Array();
console.log(typeof arr);  //object
arr[0] = 'A';
arr[1] = 12;
arr[2] = true;
arr[3] = {name:'zs',sex:'男'}

使用字面量创建数组

js 复制代码
var arr =[1,'2',3,'4',5,6,'7',8,'9'];

通过length属性 获取数组长度

遍历数组

js 复制代码
for(let i = 0; i< arr.length; i++){
    console.log(arr[i])
}

向数组的末尾追加值

js 复制代码
arr.push("唐僧");
console.log(arr);

删除末尾数据

js 复制代码
arr.pop();
console.log(arr);

向数组的开头追加一个元素或者多个元素

js 复制代码
arr.unshift("牛魔王","铁扇公主");
console.log(arr);

删除数组的第一个元素

js 复制代码
arr.shift();
console.log(arr);

For Each遍历数组 IE 8 以上

第一个参数 :当前正在遍历的元素

第二个参数 :当前正在遍历的元素索引

第三个参数:当前正在遍历的数组

js 复制代码
arr.forEach(function (value,index,arr) {
    console.log(value,index,arr);
})

slice 截取指定元素,不会改变原数组参数

  • 1.截取的开始位置索引 包含开始索引元素
  • 2.截取的结束位置索引,不包含结束索引元素
  • 可以为负数 -1 表示倒数第一个元素 -2表示倒数第二个元素
js 复制代码
let newArr = arr.slice(0,3);
let newArr = arr.slice(0,-2);
console.log("原数组:",arr);
console.log("新数组:",newArr);

splice() 可以用于删除数组中的指定元素,该方法会影响到原数组,删除的元素会作为返回值返回参数

  • 1.表示开始位置索引
  • 2.要删除的元素数量
  • 3.第三个及后续参数参数,可以作为新的元素,插入到原数组中(开始索引的前面)
js 复制代码
var result = arr.splice(1,0,'朱大姐','沙和尚')
console.log("原数组:",arr);
console.log("新数组:",newArr);

concat 可以将两个或者多个数组 连接并返回一个新的数组 不会对原数组产生影响

js 复制代码
let arr1 = ['测试数据A', '测试数据B', '测试数据C'];
let arr2 = ['测试数据1', '测试数据2', '测试数据3'];
let arr3 = ['测试数据#', '测试数据$', '测试数据%'];

let result = arr1.concat(arr2, arr3, '连接后拼接A', '连接后拼接B');
console.log("拼接后:", result);
console.log(arr1,arr2,arr3)

let arr1 = ['测试数据A', '测试数据B', '测试数据C'];
数组拼接为字符串
console.log(arr1.join("#-#"));
数组反转
console.log(arr1.reverse());

数组元素排序:

js 复制代码
var arr = [1,2,5,8,6,5,7,8,9,3]
/**
 *  如果返回大于0 则元素交换位置
 *  如果返回小于0 则元素位置不变
 *  如果等于0则认为两个元素相同
 */
arr.sort(function (a,b){
    return b-a;
});
console.log(arr);
相关推荐
Fairy_sevenseven6 分钟前
【二十八】【QT开发应用】模拟WPS Tab
开发语言·qt·wps
蜡笔小新星14 分钟前
Python Kivy库学习路线
开发语言·网络·经验分享·python·学习
凯子坚持 c14 分钟前
C语言复习概要(三)
c语言·开发语言
无限大.26 分钟前
c语言200例 067
java·c语言·开发语言
余炜yw27 分钟前
【Java序列化器】Java 中常用序列化器的探索与实践
java·开发语言
篝火悟者29 分钟前
问题-python-运行报错-SyntaxError: Non-UTF-8 code starting with ‘\xd5‘ in file 汉字编码问题
开发语言·python
Death20031 分钟前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
六点半88833 分钟前
【C++】速通涉及 “vector” 的经典OJ编程题
开发语言·c++·算法·青少年编程·推荐算法
惜.己33 分钟前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
niu_sama36 分钟前
基于muduo库函数实现protobuf协议的通信
开发语言·qt