首页 > 其他分享 >js原型和继承

js原型和继承

时间:2022-10-26 19:55:27浏览次数:51  
标签:__ console log 继承 js Person 原型 prototype 构造函数

原型

prototype

概述:prototype是属于函数的一个空间,它是一个对象.因为构造函数也是函数所以他也具备.而这个prototype属性我们称为显式原型

函数的prototype
function fn(){

}
console.log(fn.prototype);
构造函数的prototype
function Person(){

}
console.log(Person.prototype);
//获取当前的构造函数
console.log(Person.prototype.constructor);
//将函数存储在原型上
Person.prototype.sayHello = ()=>{
    console.log(this);
}
//新建对象
var person = new Person()
var person1 = new Person()
console.log(person == person1);//false
//person.sayHello ===>   Person.prototype.sayHello
//对于prototype上存储的内容 通过实例对象.属性名访问
console.log(person.sayHello == person1.sayHello);//true
///对于prototype上存储的内容 通过实例对象.属性名访问
console.log(person.constructor);
  • 从上可得构造函数的prototype是一个对象,第二个里面有个属性 constructor指向当前的构造函数。

  • 实例对象访问对应的prototype上的内容可以通过实例对象.属性名访问

  • 一般将对应的函数存储在对应prototype上(这个函数只会声明一次)。将函数存储在原型,将属性放在构造函数里面。

  • 在prototype里面声明的函数的this指向当前的调用的实例对象

__proto__

概述:

__proto__称为隐式原型,它是属于对象的一个空间,每个对象都存在这个空间,那么对应的实例对象也是一个对象,所以它也有这个空间。这个空间指向对应的构造函数的prototype。

var obj = new Object()
//每个对象都存在的一个空间 它指向对应的构造函数的prototype
console.log(obj.__proto__);
//对象的__proto__指向对应的构造函数的prototype
console.log(obj.__proto__ == Object.prototype);
function Person(){

}
var person = new Person()
console.log(person.__proto__ == Person.prototype);
// Person.prototype.sayHello = ()=>{

// }
person.__proto__.sayHello = ()=>{
    console.log('hello');
}
person.sayHello()

__proto__的指向问题

__proto__指向对应的构造函数的prototype

构造函数也是一个对象 那么它的__proto__指向谁 指向对应的父类的构造函数的prototype

Object的__proto__指向null

原型链

概述:

对象在__proto__上找属性的链式结构被称为原型链。

从上面的指向问题来看 对象在原型上找属性的过程为
  • 先找自己的__proto__ (对应的构造函数的prototype),

  • 再找对应的自身构造函数的原型的__proto__ 找到父类构造函数的原型 ,再找对应的父类的原型的__proto__,直到找到object为止

  • Object的原型的__proto__(null)上还找不到返回undefined

Object.prototype.hello = '你好'
class Person{
    constructor(){
        this.name = '张三'
    }
}
Person.prototype.sex = '女'
Person.prototype.username = 'rose'
//对象赋值 有就重新赋值 没有就添加属性赋值
Person.hi = '你好吗'
var person = new Person()
person.age = '109'
class Son extends Person{
    constructor(){
        super()
        this.age = '李四'
    }
}
Son.prototype.sex = '男'
//实例化对象
var son = new Son()
console.log(son.age);//李四
console.log(son.name);//张三
console.log(son.username);//rose
console.log(son.sex);//男
console.log(son.hello);//你好 
console.log(son.hi);//undefined

总结

  • 构造函数的原型prototype

  • 实例对象的原型__proto__

  • 实例对象的__proto__指向构造函数的prototype

  • 原型链通过对应的对象的__proto__去找对应的属性 直到找到Object为止

  • 原型一般上面写函数,可以保证函数只声明一次。对应的属性写在构造函数内。

  • 原型上的方法/属性。通过实例对象.属性名直接访问(平常通过对象去点的方法都称为原型方法)

  • 在对应的原型上的函数里面的this指向当前调用的实例对象

面向对象的三大特性

封装 (函数的抽取 属性的抽取)

继承 (子类继承父类)

多态 (重写 子类重写父类方法)

继承

概述:

子类继承父类的属性和方法(非私有的属性和方法 非静态的方法)

继承的实现

使用extends关键词实现继承(es6新增 类的继承)
// es6新增类的继承 extends关键词实现
class Person{
    constructor(){
        this.name = 'jack'
    }
}
class Son extends Person{
    constructor(age){
        super()
        this.age = age
    }
}
var son = new Son(18)
console.log(`son`, son);
原型链继承 (覆盖之前原型上的所有方法 显示的时候不会显示继承来的属性 (在原型上重复出现一样的属性))
  • 核心 在子类的原型上创建父类的对象

function Person(){
    this.name = 'jack'
}
function Son(age){
    this.age = age
}
Son.prototype.say = ()=>{
    console.log(`你好`);
}
//原型继承
// 将要继承的类放在继承的子类的原型上
//原型链会覆盖原本原型上的私有的方法及属性
Son.prototype = new Person()
var son = new Son(18)
console.log(`son`, son);
console.log(son.name);
// son.say() 
对象冒充 (会显示继承的属性 不能继承原型上的方法)
  • 核心 在子类中调用父类的构造函数 更改this指向

function Person(){
    this.name = 'jack'
}
function Son(age){
    //改this指向 执行父类的构造函数
    Person.call(this)
    this.age = age
}
var son = new Son(18)
console.log(`son`, son);

组合继承 (使用原型链继承和对象冒充结合)

// 组合继承 原型链继承加对象冒充
function Person(){
    this.name = 'jack'
}
Person.prototype.say = ()=>{
    console.log(`hello`);
}
function Son(age){
    //改this指向 执行父类的构造函数
    Person.call(this)
    this.age = age
}
//原型链继承
Son.prototype = new Person()
var son = new Son(18)
console.log(`son`, son);
son.say()

 

标签:__,console,log,继承,js,Person,原型,prototype,构造函数
From: https://www.cnblogs.com/tch001/p/16829806.html

相关文章

  • JS之dom元素和位置有关的属性计算方式
    以下全部属性皆为横向(因为竖向的话只需要把x改为y即可,就不在本文列出) 1.clientWidth:元素内部宽度=width+padding2.offsetWidth:元素内部宽度=width+padding+border+scr......
  • 面试 考察js基础不能不会的内容(第五天)
    01、描述事件冒泡的流程基于DOM树结构,事件会顺着触发元素向上冒泡点击一个div,会一级一级向父级、爷级元素上冒泡,这个点击事件不仅能被这个div捕捉到,也能被他的父级、爷......
  • vue-js中键盘事件编码
    js里面的键盘事件经常用到的:keyCode8=BackSpaceBackSpacekeyCode9=TabTabkeyCode12=ClearkeyCode13=EnterkeyCode16=Shift_LkeyCode17=Control_Lkey......
  • apijson 初探
    apijson初探本文试着从5W1H角度切入,试图快速建立自己对apijson的整体认知,所以这不是一趟快速入门的demo之旅,而是显得比较务虚的探索式知识体系整合。1、Why前后......
  • 几行JS代码防止网站在QQ和微信被举报
    1<div>2<script>3//跳转提示45if(is_weixn_qq()){;67window.location.href=‘https://c.pc.qq.com/middle.html?pfurl=’+window.location.hre......
  • vue.js+canvas实现随机验证码
    登录注册啥的,不需要下载插件,上图:<template><divclass="about"><p>当前验证码:{{codeStr}}</p><canvasid="canvas"width="100"height="43"@click="cr......
  • react-json-view
    react-json-viewreact-json-view示例//importthereact-json-viewcomponentimportReactJsonfrom'react-json-view'//usethecomponentinyourapp!<ReactJs......
  • 防抖节流的含义使用场景及js实现原理
    1.防抖:n秒后在执行该事件,若在n秒内被重复触发,则重新计时。代码实现重在清零clearTimeout。应用:登录,提交,浏览器窗口的resizes事件,文本编辑保存//防抖函数f......
  • 请谨慎选择JS加密工具站
    前言JS加密原本是一个造福于广大群主的产品,它可以很好的保护你的前端JS代码,为您的前端代码保驾护航,还可以保证您的接口参数签名计算代码不泄露出去,防止别有用心的人随意的去......
  • jsp项目运行过程中出现的问题:
    报错问题描述:/admin/insert.jsp(行.:[33],列:[7])根据标记文件中的TLD或attribute指令,attribute[items]不接受任何表达式   web.xml中版本号不兼容产生的问......