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

相关文章

Java利用Spire.XLS for Java自动化设置Excel的文档属性

《Java利用Spire.XLSforJava自动化设置Excel的文档属性》一个专业的Excel文件,其文档属性往往能大大提升文件的可管理性和可检索性,下面我们就来看看Java如何使用Spire... 目录Spire.XLS for Java 库介绍与安装Java 设置内置的 Excel 文档属性Java

MybatisPlus中几种条件构造器运用方式

《MybatisPlus中几种条件构造器运用方式》QueryWrapper是Mybatis-Plus提供的一个用于构建SQL查询条件的工具类,提供了各种方法如eq、ne、gt、ge、lt、le、lik... 目录版本介绍QueryWrapperLambdaQueryWrapperUpdateWrapperL

HTML5的input标签的`type`属性值详解和代码示例

《HTML5的input标签的`type`属性值详解和代码示例》HTML5的`input`标签提供了多种`type`属性值,用于创建不同类型的输入控件,满足用户输入的多样化需求,从文本输入、密码输入、... 目录一、引言二、文本类输入类型2.1 text2.2 password2.3 textarea(严格

input的accept属性让文件上传安全高效

《input的accept属性让文件上传安全高效》文章介绍了HTML的input文件上传`accept`属性在文件上传校验中的重要性和优势,通过使用`accept`属性,可以减少前端JavaScrip... 目录前言那个悄悄毁掉你上传体验的“常见写法”改变一切的 html 小特性:accept真正的魔法:让

C#借助Spire.XLS for .NET实现在Excel中添加文档属性

《C#借助Spire.XLSfor.NET实现在Excel中添加文档属性》在日常的数据处理和项目管理中,Excel文档扮演着举足轻重的角色,本文将深入探讨如何在C#中借助强大的第三方库Spire.... 目录为什么需要程序化添加Excel文档属性使用Spire.XLS for .NET库实现文档属性管理Sp

MySQL 数据库进阶之SQL 数据操作与子查询操作大全

《MySQL数据库进阶之SQL数据操作与子查询操作大全》本文详细介绍了SQL中的子查询、数据添加(INSERT)、数据修改(UPDATE)和数据删除(DELETE、TRUNCATE、DROP)操作... 目录一、子查询:嵌套在查询中的查询1.1 子查询的基本语法1.2 子查询的实战示例二、数据添加:INSE

Java Exception异常类的继承体系详解

《JavaException异常类的继承体系详解》Java中的异常处理机制分为异常(Exception)和错误(Error)两大类,异常分为编译时异常(CheckedException)和运行时异常... 目录1. 异常类的继承体系2. Error错误3. Exception异常3.1 编译时异常: Che

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

vue监听属性watch的用法及使用场景详解

《vue监听属性watch的用法及使用场景详解》watch是vue中常用的监听器,它主要用于侦听数据的变化,在数据发生变化的时候执行一些操作,:本文主要介绍vue监听属性watch的用法及使用场景... 目录1. 监听属性 watch2. 常规用法3. 监听对象和route变化4. 使用场景附Watch 的

在Node.js中使用.env文件管理环境变量的全过程

《在Node.js中使用.env文件管理环境变量的全过程》Node.js应用程序通常依赖于环境变量来管理敏感信息或配置设置,.env文件已经成为一种流行的本地管理这些变量的方法,本文将探讨.env文件... 目录引言为什么使php用 .env 文件 ?如何在 Node.js 中使用 .env 文件最佳实践引