js进阶一(prototype、prototype指向、原型继承、构造继承、组合继承、为window赋值新属性)

本文主要是介绍js进阶一(prototype、prototype指向、原型继承、构造继承、组合继承、为window赋值新属性),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

      • prototype
      • prototype中方法互相访问
      • prototype中找寻属性、方法
      • 改变prototype指向
      • 内置对象添加prototype方法
      • window全局对象
      • 通过原型实现继承
      • 继承例子
      • 借用构造函数
      • 组合继承

prototype

原型?
实例对象中有__proto__这个属性,叫原型,也是一个对象,这个属性是给浏览器使用,不是标准的属性----->proto----->可以叫原型对象

构造函数中有prototype这个属性,叫原型,也是一个对象,这个属性是给程序员使用,是标准的属性------>prototype—>可以叫原型对象

实例对象的__proto__和构造函数中的prototype相等—>true
又因为实例对象是通过构造函数来创建的,构造函数中有原型对象prototype
实例对象的__proto__指向了构造函数的原型对象prototype

通过原型来添加方法,解决数据共享,节省内存空间

我们来看一个例子

function Person(name, age) {this.name = name;this.age = age;}//通过原型来添加方法,解决数据共享,节省内存空间Person.prototype.eat = function () {console.log("吃凉菜");};var p1 = new Person("小明", 20);p1.__proto__.eat();p1.eat()Person.prototype.eat()console.log(p1.constructor == Person);console.log(p1.__proto__.constructor == Person);console.log(p1.__proto__ == Person.prototype);console.log(p1.__proto__.constructor == Person.prototype.constructor);

输出如下:

吃凉菜
吃凉菜
true
true
true
true

原型指向可以改变
实例对象的原型__proto__指向的是该对象所在的构造函数的原型对象

实例对象中有__proto__原型
构造函数中有prototype原型
prototype是对象
所以,prototype这个对象中也有__proto__,那么指向了哪里
实例对象中的__proto__指向的是构造函数的prototype
所以,prototype这个对象中__proto__指向的应该是某个构造函数的原型prototype

function Person() {}
Person.prototype.eat=function () {console.log("吃东西");
};var per=new Person();
console.dir(per);
console.dir(Person);console.log(Person.prototype.__proto__);//per实例对象的__proto__------->Person.prototype的__proto__---->Object.prototype的__proto__是nullconsole.log(per.__proto__==Person.prototype);
console.log(per.__proto__.__proto__==Person.prototype.__proto__);
console.log(Person.prototype.__proto__==Object.prototype);
console.log(Object.prototype.__proto__);

输出如下:

Personƒ Person()
{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
true
true
true
null

prototype中方法互相访问

 function Animal(name,age) {this.name=name;this.age=age;}//原型中添加方法Animal.prototype.eat=function () {console.log("动物吃东西");this.play();};Animal.prototype.play=function () {console.log("玩球");};var dog=new Animal("小苏",20);dog.eat();

输出如下:

动物吃东西
玩球

prototype中找寻属性、方法

实例对象使用的属性或者方法,先在实例中查找,找到了则直接使用,找不到则,去实例对象的__proto__指向的原型对象prototype中找,找到了则使用,找不到则报错

function Person(age,sex) {this.age=age;//年龄this.sex=sex;this.eat=function () {console.log("构造函数中的吃");};}Person.prototype.sex="女";Person.prototype.eat=function () {console.log("原型对象中的吃");};var per=new Person(20,"男");console.log(per.sex);//男per.eat();

输出如下:

男
构造函数中的吃

我们在看下面一个例子:

function Person(age,sex) {this.age=age;this.sex=sex;}Person.prototype.sex="女";var per=new Person(10,"男");console.log(per.sex);//因为JS是一门动态类型的语言,对象没有什么,只要点了,那么这个对象就有了这个东西,没有这个属性,只要对象.属性名字,对象就有这个属性了,但是,该属性没有赋值,所以,结果是:undefinedconsole.log(per.fdsfdsfsdfds);

输出如下:

男
undefined

改变prototype指向

原型指向可以改变
实例对象的原型__proto__指向的是该对象所在的构造函数的原型对象
构造函数的原型对象(prototype)指向如果改变了,实例对象的原型(proto)指向也会发生改变

原型的指向是可以改变的
实例对象和原型对象之间的关系是通过__proto__原型来联系起来的,这个关系就是原型链

function Person(age) {this.age = age;}Person.prototype.eat = function () {console.log("人正在吃东西");};//学生构造函数function Student(sex) {this.sex = sex;}//学生的原型中添加方法----先在原型中添加方法Student.prototype.sayHi = function () {console.log("您好哦");};//改变了Student原型对象的指向Student.prototype = new Person(10);var stu = new Student("男");stu.eat();//  stu.sayHi();console.info(stu.sex)console.info(stu.age)console.dir(stu)

输出如下:

人正在吃东西
男
10Studentsex: "男"__proto__: Personage: 10__proto__:eat: ƒ ()constructor: ƒ Person(age)__proto__: Object

内置对象添加prototype方法

 String.prototype.sayHi = function () {console.log(this + "哈哈,萨芬");};//字符串就有了打招呼的方法var str2 = "sadly";str2.sayHi();

window全局对象

<script>//通过自调用函数产生一个随机数对象,在自调用函数外面,调用该随机数对象方法产生随机数(function (window) {//产生随机数的构造函数function Random() {}//在原型对象中添加方法Random.prototype.getRandom = function (min, max) {return Math.floor(Math.random() * (max - min) + min);};//把Random对象暴露给顶级对象window--->外部可以直接使用这个对象window.Random = Random;})(window);//实例化随机数对象var rm = new Random();//调用方法产生随机数console.log(rm.getRandom(0, 5));//全局变量</script>

通过原型实现继承

function Person(name, age, sex) {this.name = name;this.sex = sex;this.age = age;}Person.prototype.eat = function () {console.log("人可以吃东西");};Person.prototype.sleep = function () {console.log("人在睡觉");};Person.prototype.play = function () {console.log("生活就是不一样的玩法而已");};function Student(score) {this.score = score;}//改变学生的原型的指向即可==========>学生和人已经发生关系Student.prototype = new Person("小明", 10, "男");Student.prototype.study = function () {console.log("学习很累很累的哦.");};//相同的代码太多,造成了代码的冗余(重复的代码)var stu = new Student(100);console.log(stu.name);console.log(stu.age);console.log(stu.sex);stu.eat();stu.play();stu.sleep();console.log("下面的是学生对象中自己有的");console.log(stu.score);stu.study();console.dir(stu)

输出结果如下:

小明
10
男
人可以吃东西
生活就是不一样的玩法而已
人在睡觉
下面的是学生对象中自己有的
100
学习很累很累的哦.

在这里插入图片描述

继承例子

//动物的构造韩素function Animal(name,weight) {this.name=name; this.weight=weight;}//动物的原型的方法Animal.prototype.eat=function () {console.log("天天吃东西,就是吃");};//狗的构造函数function Dog(color) {this.color=color;}Dog.prototype=new Animal("哮天犬","50kg");Dog.prototype.bitePerson=function () {console.log("哼~汪汪~咬死你");};//哈士奇function ErHa(sex) {this.sex=sex;} ErHa.prototype=new Dog("黑白色");ErHa.prototype.playHost=function () {console.log("哈哈~要坏衣服,要坏桌子,拆家..嘎嘎...好玩,开心不,惊喜不,意外不");};var erHa=new ErHa("雄性");console.log(erHa.name,erHa.weight,erHa.color);erHa.eat();erHa.bitePerson();erHa.playHost();console.info(erHa)

效果如下:

哮天犬 50kg 黑白色
天天吃东西,就是吃
哼~汪汪~咬死你
哈哈~要坏衣服,要坏桌子,拆家..嘎嘎...好玩,开心不,惊喜不,意外不

在这里插入图片描述

借用构造函数

为了数据共享,改变原型指向,做到了继承—通过改变原型指向实现的继承
缺陷:因为改变原型指向的同时实现继承,直接初始化了属性,继承过来的属性的值都是一样的了,所以,这就是问题
只能重新调用对象的属性进行重新赋值,

借用构造函数:构造函数名字.call(当前对象,属性,属性,属性…);
解决了属性继承,并且值不重复的问题
缺陷:父级类别中的方法不能继承

function Person(name, age, sex, weight) {this.name = name;this.age = age;this.sex = sex;this.weight = weight;}Person.prototype.sayHi = function () {console.log("您好");};function Student(name,age,sex,weight,score) {//借用构造函数Person.call(this,name,age,sex,weight);this.score = score;}var stu1 = new Student("小明",10,"男","10kg","100");console.log(stu1.name, stu1.age, stu1.sex, stu1.weight, stu1.score);var stu2 = new Student("小红",20,"女","20kg","120");console.log(stu2.name, stu2.age, stu2.sex, stu2.weight, stu2.score);

输出如下:

小明 10 男 10kg 100
小红 20 女 20kg 120

组合继承

function Person(name, age, sex) {this.name = name;this.age = age;this.sex = sex;}Person.prototype.sayHi = function () {console.log("阿涅哈斯诶呦");};function Student(name, age, sex, score) {//借用构造函数:属性值重复的问题十神Person.call(this, name, age, sex);this.score = score;}//改变原型指向----继承Student.prototype = new Person();//不传值Student.prototype.eat = function () {console.log("吃东西");};var stu = new Student("小黑", 20, "男", "100分");console.log(stu.name, stu.age, stu.sex, stu.score);stu.sayHi();stu.eat();console.dir(stu)

输出结果如下:

小黑 20 男 100分
阿涅哈斯诶呦
吃东西

在这里插入图片描述

这篇关于js进阶一(prototype、prototype指向、原型继承、构造继承、组合继承、为window赋值新属性)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1125128

相关文章

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

如何使用Python实现一个简单的window任务管理器

《如何使用Python实现一个简单的window任务管理器》这篇文章主要为大家详细介绍了如何使用Python实现一个简单的window任务管理器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 任务管理器效果图完整代码import tkinter as tkfrom tkinter i

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

C#原型模式之如何通过克隆对象来优化创建过程

《C#原型模式之如何通过克隆对象来优化创建过程》原型模式是一种创建型设计模式,通过克隆现有对象来创建新对象,避免重复的创建成本和复杂的初始化过程,它适用于对象创建过程复杂、需要大量相似对象或避免重复初... 目录什么是原型模式?原型模式的工作原理C#中如何实现原型模式?1. 定义原型接口2. 实现原型接口3

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

HTML5 data-*自定义数据属性的示例代码

《HTML5data-*自定义数据属性的示例代码》HTML5的自定义数据属性(data-*)提供了一种标准化的方法在HTML元素上存储额外信息,可以通过JavaScript访问、修改和在CSS中使用... 目录引言基本概念使用自定义数据属性1. 在 html 中定义2. 通过 JavaScript 访问3.

CSS模拟 html 的 title 属性(鼠标悬浮显示提示文字效果)

《CSS模拟html的title属性(鼠标悬浮显示提示文字效果)》:本文主要介绍了如何使用CSS模拟HTML的title属性,通过鼠标悬浮显示提示文字效果,通过设置`.tipBox`和`.tipBox.tipContent`的样式,实现了提示内容的隐藏和显示,详细内容请阅读本文,希望能对你有所帮助... 效

MySQL进阶之路索引失效的11种情况详析

《MySQL进阶之路索引失效的11种情况详析》:本文主要介绍MySQL查询优化中的11种常见情况,包括索引的使用和优化策略,通过这些策略,开发者可以显著提升查询性能,需要的朋友可以参考下... 目录前言图示1. 使用不等式操作符(!=, <, >)2. 使用 OR 连接多个条件3. 对索引字段进行计算操作4

解读为什么@Autowired在属性上被警告,在setter方法上不被警告问题

《解读为什么@Autowired在属性上被警告,在setter方法上不被警告问题》在Spring开发中,@Autowired注解常用于实现依赖注入,它可以应用于类的属性、构造器或setter方法上,然... 目录1. 为什么 @Autowired 在属性上被警告?1.1 隐式依赖注入1.2 IDE 的警告: