当前位置: 首页 > news >正文

罗山网站建设比较靠谱的电商培训机构

罗山网站建设,比较靠谱的电商培训机构,网站建设客户去哪找,做网站wordpress一.什么是原型与原型链 根据MDN官方解释: JavaScript 常被描述为一种基于原型的语言——每个对象拥有一个原型对象[[Prototype]] ,对象以其原型为模板、从原型继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类…

一.什么是原型与原型链

根据MDN官方解释: JavaScript 常被描述为一种基于原型的语言——每个对象拥有一个原型对象[[Prototype]] ,对象以其原型为模板、从原型继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。

以前可以通过__proto__访问原型,但现在它已经从相关web标准中被移除,后续可通过Object.getPrototypeOf(obj)来获取原型。在 javascript 中,函数可以有属性。每个函数都有一个特殊的属性叫作原型(prototype),而它主要是用作继承

二.原型的作用

之所以存在原型,是因为JS语言需要实现面向对象,而原型是面向对象的实现手段之一。一个能支持面向对象的语言必须做到一点:能判断一个实例的类型. 在JS中,通过原型就可以知晓某个对象从属于哪个类型,换句话说,原型的存在避免了类型的丢失。在使用方面,有了原型就可以抽离实例的公共方法到原型上,这样就避免了把方法放到实例中,从而减少了内存的消耗。

三.隐式原型和显示原型的区别

在过去我们常用__proto__表示隐式原型(它其实就是[[Prototype]])。用prototype代表显示原型。
每个对象(数组,对象,函数)都有自己的__proto__,通过__proto__可以添加数据到原型,也可以通过它一层一层查找数据。构造函数默认会有prototype属性,prototype属性是用来继承的,实例化之后__proto会指向构造函数的prototype。

四.JS的继承

父类

function Person(name) {this.name = namethis.say = function () {console.log('1 + 1 = 2')}this.colors = ["red", "blue", "green"];
}Person.prototype.listen = function () {console.log('エウテルペ')
}Person.prototype.sayName = function () { // 父类原型方法return this.name;};

4.1 原型继承

将父类的实例作为子类的原型

缺点:

  • 无法实现多继承,即一个子类不能同时继承多个父类
  • 所有实例共享同一个父类的原型,修改子类的原型会影响父类的原型
  • 创建子类实例时,无法向父类构造函数传参
// TODO:思路:将父类的实例作为子类的原型
function Student() {this.type = "学生"this.name = "张三"
}Student.prototype = new Person('人') //TODO:关键点 通过原型继承父类 =>无法实现多继承,即一个子类不能同时继承多个父类
Student.prototype.xx = 123
Student.prototype.fn = ()=>{}const zhangsan = new Student()
console.log(zhangsan);Person.prototype.eat = function () {console.log('吃东西')
}
console.log(zhangsan);// TODO:缺点
// 1 无法实现多继承,即一个子类不能同时继承多个父类
// 2 所有实例共享同一个父类的原型
function Student2() {this.type = "学生"this.name = "张三"
}
Student2.prototype = new Person('人2')
// 3 创建子类实例时,无法向父类构造函数传参
const lisi = new Student2()

4.2 构造继承

在子类的构造函数内部调用父类构造函数并改变构造函数的this指向。

缺点:

  • 父类原型上的属性没有继承过来
  • 因为原型没有继承过来所以无法实现函数复用,每个子类都有父类构造函数的副本,影响性能
  • 实例并不是父类的实例,只是子类的实例
// TODO:思路:在子类型的构造函数内部调用父类构造函数并改变构造函数的this指向。
function Student(name) {// this.person = new Person(name)Person.call(this,name) // TODO:关键点this.age = 16
}
Student.prototype.run = '跑路'
const lisi = new Student('李四') // 能实现多继承 可以向父类传递参数
// 优点
// 解决了所有实例共享同一个父类的原型,实现多继承,创建子类实例时,可以向父类传递参数
// TODO:缺点
// 1 父类原型上的属性没有继承过来
function Student2(name) {Person.call(this,name)this.age = 18
}
// 2 因为原型没有继承过来所以无法实现函数复用,每个子类都有父类构造函数的副本,影响性能// 3 实例并不是父类的实例,只是子类的实例(只是实例化了Student,根本就没有实例化Person)
const zhangsan = new Student('张大帅')

4.3 组合继承

顾名思义,组合继承就是将原型链继承与构造函数继承组合在一起,从而发挥两者之长的一种继承模式。

缺点:

  • 所有实例共享同一个父类的原型,修改子类的原型会影响父类的原型
  • 调用了两次父类的构造函数
// TODO:思路:顾名思义,组合继承就是将原型链继承与构造函数继承组合在一起,从而发挥两者之长的一种继承模式。
function Student(name, subName) {Person.call(this, name) // 构造继承 第一次调用构造函数this.subName = subName;
}
Student.prototype = new Person() // TODO:关键点 原型继承 第二次调用构造函数
// Student.prototype = Person.prototype
Student.prototype.constructor = Student // 组合继承需要修复构造函数指向?
Student.prototype.saySubName = function () { // 子类原型方法return this.subName;
}// 子类实例
let instance = new Student('王五', 'sisterAn')
instance.colors.push('black')
console.log(instance.colors) // ["red", "blue", "green", "black"]
console.log(instance.sayName()) // 王五
console.log(instance.saySubName()) // sisterAn
console.log(instance);let instance1 = new Student('赵六', 'sisterAn1')
console.log(instance1.colors) //  ["red", "blue", "green"]
console.log(instance1.sayName()) // 赵六
console.log(instance1.saySubName()) // sisterAn1
console.log(instance1);
// 优点:解决了构造继承的缺陷,可以继承原型属性/方法,实现复用
// TODO:缺点:调用了两次父类的构造函数

4.4 寄生组合继承

通过原型链的混成形式来继承方法,在组合继承的基础上.利用 Object.create() 将Person.prototype通过原型的方式继承给一个对象,这样的访问顺序就还是保持子类优先,同时后续添加原型也不会影响父类的原型

优点:

  • 解决了组合继承的缺陷,只调用一次父类的构造函数
  • 修改子类的原型,父类不变

补充

  • Student.prototype.isPrototypeOf(instance)
    • 用于检测构造函数Student.prototype是否存在于另一个对象instance的原型链上
  • instance instanceof Student
    • 用于检测实例对象instance的原型链上是否存在构造函数Student的 prototype。
// TODO:思路:通过原型链的混成形式来继承方法
function Student(name, subName) {Person.call(this, name) // 构造继承this.subName = subName;
}
// 用 Object.create() 将参数1通过原型的方式继承给参数2,这样的访问顺序就还是保持子类优先,同时后续添加原型也不会影响父类的原型
console.log(Object.create(Person.prototype));
Student.prototype = Object.create(Person.prototype, {varB : {value: null,enumerable: true,configurable: true,writable: true},doSomething : {value: function(){ // overrideA.prototype.doSomething.apply(this, arguments);// call super// ...},enumerable: true,configurable: true,writable: true}}); // TODO:关键点
Student.prototype.constructor = Student // 组合继承需要修复构造函数指向// 子类实例
let instance = new Student('王五', 'sisterAn')
instance.colors.push('black')
console.log(instance.colors) // ["red", "blue", "green", "black"]
console.log(instance.sayName()) // 王五
console.log(instance.doSomething())
console.log(instance);let instance1 = new Student('赵六', 'sisterAn1')
console.log(instance1.colors) //  ["red", "blue", "green"]
console.log(instance1.sayName()) // 赵六
console.log(instance1.doSomething())
console.log(instance1);
// 优点:解决了组合继承的缺陷,只调用一次父类的构造函数,原型链保持不变
// Student.prototype.isPrototypeOf(instance) true // 用于检测构造函数Student.prototype是否存在于另一个对象instance的原型链上
// instance instanceof Student // 用于检测实例对象instance的原型链上是否存在构造函数Student的 prototype。

4.5 ES6继承

可以理解ES6继承就是组合寄生继承的一个语法糖.

使用

class People {constructor(name) {this.name = name}run() { }
}// extends 相当于方法的继承
// 替换了上面的3行代码
class Man extends People {constructor(name) {// super 相当于属性的继承// 替换了 People.call(this, name)super(name)this.gender = '男'}fight() { }
}

extends 继承的核心代码如下,其实和寄生组合式继承方式一样

function _inherits(subType, superType) {// 创建对象,Object.create 创建父类原型的一个副本// 增强对象,弥补因重写原型而失去的默认的 constructor 属性// 指定对象,将新创建的对象赋值给子类的原型 subType.prototypesubType.prototype = Object.create(superType && superType.prototype, {constructor: { // 重写 constructorvalue: subType,enumerable: false,writable: true,configurable: true}});if (superType) {Object.setPrototypeOf? Object.setPrototypeOf(subType, superType): subType.__proto__ = superType;}
}

五.关于Object.prototype.__proto__已经弃用

后续可通过Object.getPrototypeOf(obj)来获取原型!
在这里插入图片描述

示例

let Circle = function () {};
let shape = {};
let circle = new Circle();// 设置该对象的原型链引用
// 过时且不推荐使用的。这里只是举个例子,尽量不要在生产环境中这样做。
shape.__proto__ = circle;// 判断该对象的原型链引用是否属于 circle
console.log(shape.__proto__ === circle); // true
http://www.tj-hxxt.cn/news/122295.html

相关文章:

  • 网站开发名片怎么做百度贴吧网页版
  • 网页搜索图片漯河seo推广
  • 南京 百度 网站建设近三年成功的营销案例
  • 网站备案有什么好处百度竞价推广屏蔽软件
  • 网站文章批量上传工具淘宝直通车推广怎么做
  • 网站免费做链接企业宣传标语
  • 任何网站都可以做谷歌推广的吗百度搜索下载安装
  • 各大网站的名字大全免费网络推广网址
  • 网站服务器中如何做重定向手机自己怎么建电影网站
  • 做物流网站的公司吗百度营销app
  • 网站建设音乐插件怎么弄谷歌搜索引擎怎么才能用
  • 制作短视频的app哪个好旅游seo整站优化
  • 合肥网站设计服务短视频运营公司
  • 安庆网站建设哪家好如何做好网络营销
  • 人人做全免费网站seo关键词优化的技巧和方法
  • 人力招聘网站建设游戏代理是怎么赚钱的如何代理游戏
  • 网站备案 企业 个人互联网推广销售
  • wordpress导航栏郑州网站推广优化
  • 免费wordpress 主题下载地址廊坊网站建设优化
  • 什么网站做批发零食的很多如何建立免费个人网站
  • 校园云网站建设百度问答兼职怎么做
  • 网站前台设计工具seo短视频入口引流
  • 食品网站的功能定位免费推广网站2023mmm
  • 上海小程序开发哪家好厦门网站推广优化哪家好
  • 国内wordpress主题网站广州网页推广公司
  • 怎么在wordpress建英文网站企业网站建设服务
  • 营销型网站设计难不难新闻软文广告
  • ps做网站首页步骤活动策划方案详细模板
  • 谷歌网站推广策略方案全网自媒体平台
  • 网站正能量就是一打开全是的收录网站