| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> JavaScript知识库 -> 面向对象继承 -> 正文阅读 |
|
[JavaScript知识库]面向对象继承 |
一、原型 {Prototype}(花括号的原型是隐藏的链接)是一个隐藏的链接,用户无法直接访问该对象。这个隐藏的链接也是一个对象。因此,有三种方法可以在JavaScript中创建对象,并且每种方法都可以创建原型链接。 目的:1、节省内存空间,2、实现数据共享 原型链:实例与原型的链条称作?原型链 二、原型的指向是否可以改变 原型对象的constructor属性指向构造函数本身 ??Student.prototype?=?new?Person("小王",?18); ??console.log(Person.prototype.constructor?===?Person)//true ??console.log(Student.prototype.constructor?===?Student)//false 学生原型指向人的构造函数。 结论:原型的指向可以发生改变。 三、原型链最终指向了哪里 每一个对象都与一个可以继承属性的原型对象相关联。从对象文字创建的所有对象都链接到Object.prototype,这是一个JavaScript标准对象。 任何一个对象都有__proto__属性,实例化对象的__proto__属性指向的的构造函数的原型,因为任何一个对象都有__proto__属性,原型也是对象,所以原型也有__proto__属性,原型也有__proto__属性指向哪里呢? 猜测:原型的_proto__属性指向某个构造函数的原型 Object构造函数的原型 ?console.log(Person.prototype); ??console.log(Person.prototype.__proto__); ??console.log(Person.prototype.__proto__?===?Object.prototype); Object.prototype也是对象,所以Object.prototype也有__proto__属性,指向哪儿? ?console.log(Object.prototype.__proto__);//null ?console.log(Object.prototype.__proto__?===?null);//true 最终结论:原型链最终指向了null 四、继承 原型继承 是因为原型的constructor指向构造函数。 又因为原型链的指向可以发生变化。 所以子类去继承父类的所有的属性和方法,就让学生的原型指向父类即可。 Student.prototype.className?=?"一班"; ??Student.prototype.playLove?=?function?()?{ ????console.log(this.name?+?"爱搞对象!"); ??}?? Student.prototype?=?new?Person("小王",?18); console.log(Student.prototype.constructor?===?Person);//true 为什么获取不到学生原型中的属性和方法?是因为设置完学生的原型中的属性和方法后,学生的原型指向发生改变了 解决办法:将学生原型的设置放在原型改变之后即可 ?Student.prototype?=?new?Person("小王",?18); ??console.log(Student.prototype.constructor?===?Person);//true ??Student.prototype.className?=?"一班"; ??Student.prototype.playLove?=?function?()?{ ????console.log(this.name?+?"爱搞对象!"); ??} 通过原型继承,子类本身构造函数中的属性和方法以及子类原型中的属性和方法都可以获取到 并且父类构造函数中的属性和方法以及父类原型中的属性和方法也可以获取到。 构造函数继承 call方法的作用 1、函数名.call()可以实现函数的调用 function?fn1()?{ ????console.log("我是普通函数"); ??} ??//?fn1(); ??fn1.call(); 2、call()会改变this指向,如果没有参数this指向window ?var?name?=?"小丽"; ??var?obj1?=?{ ????name:?"小王", ????say:?function?()?{ ??????console.log(this.name?+?"爱说话!"); ????} ??} ??obj1.say();//小王爱说话! ??obj1.say.call();//小丽爱说话! ????????3.call()会改变this指向,如果有参数this指向该参数 ?var?obj2?=?{ ????name:?"小刚", ????say:?function?()?{ ??????console.log(this.name?+?"爱说话!"); ????} ??} ??obj2.say.call(obj1);//小王爱说话! Call方法实现继承 call()会改变this指向,如果有参数this指向该参数中第一个参数,剩下的参数是个参数列表 我们可以通过call方法改变this指向的特性去实现继承,?构造函数中的this指向实例化对象 ?function?Student(score,?name,?age)?{ ????this.score?=?score; ????this.study?=?function?()?{ ??????console.log(this.name?+?"爱学习!"); ????} ????Person.call(this,?name,?age); ??} 深拷贝与浅拷贝 1.javascript变量包含两种不同数据类型的值:基本类型和引用类型。 基本类型值指的是简单的数据段,包括es6里面新增的一共是有6种,具体如下:number、string、boolean、null、undefined、symbol。 引用类型值指那些可能由多个值构成的对象,只有一种如下:object。 2.javascript的变量的存储方式:栈(stack)和堆(heap)。 栈:自动分配内存空间,系统自动释放,里面存放的是基本类型的值和引用类型的地址 堆:动态分配的内存,大小不定,也不会自动释放。里面存放引用类型的值。 如图!👇
基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值。 基本类型与引用类型最大的区别实际就是 传值与传址 的区别 值传递:基本类型采用的是值传递。 引用类型占用空间不固定,保存在堆中(当我们在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(因为对象的创建成本通常较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(方法的参数传递时很常见),则这个对象依然不会被销毁,只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它 ? 浅拷贝 定义:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。”里面的对象“会在原来的对象和它的副本之间共享。 自己总结: 简单来说就是一个手机和一个投影画面。手机投影到投影仪上,手机和投影仪的画面是同步的,手机关闭,投影仪也关闭---这叫做浅拷贝!! else! 手机关闭,投影仪不关闭(变成自我独立的了,好比如漩涡鸣人的影分身突然不听话了,独立生存了)----这就是深拷贝!! 基本数据类型Number(赋值操作) var a=1; var b=a; b //1 b=2; b //2 ?a //1 数组 var arr1 = [1,2,3]; ?var arr2 = arr1; arr2 //[1,2,3] arr2.push(4); arr2 //[1,2,3,4] arr1 //[1,2,3,4] ? ? ? ? ? 对象 var obj1={count:1,name:'grace',age:1}; var obj2 = obj1; obj2 //{count:1,name:'grace',age:1} obj2.count=2; obj1 //{count:2,name:'grace',age:1} obj2 //{count:2,name:'grace',age:1} 深拷贝 定义:深拷贝不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上,所以对一个对象的修改并不会影响另一个对象。 数组(注意:该数组只是单纯的数组,如果数组里面嵌套对象,则下面的几种方法都不是深拷贝。)? 法一:for循环 var arr1 = [1,2,3]; var arr2 = copyArr(arr1); ?function copyArr(arr){ ?????????????? var res=[]; ?????????????? for(var i=0,length=arr.length;i<length;i++) ?????????????? { ????????????????????????????????? res.push(arr[i]); ?????????????? } return res; } 法二: slice var arr1 = [1,2,3]; var arr2 = arr1.slice(0); 法三: concat var arr1 = [1,2,3]; var arr2 = arr1.concat(); 对象 法一:for循环 let obj1={count:1,name:'grace',age:1}; let obj2 = copyObj(obj){ ?let res = {}; for(let key in obj){ res[key]=obj[key]; } ?return res; } 函数内this的指向 函数也是对象 函数是一种特殊的引用类型 ??function?fn1()?{ ??} ??console.log(typeof?fn1); ??//?本质是 ??var?fn2?=?new?Function("num1",?"return?num1"); ??console.log(fn2(666)); ??console.log(fn2.__proto__?==?Function.prototype);//true ??//?函数也是对象 ? 希望阔以帮助到您哟 |
|
JavaScript知识库 最新文章 |
ES6的相关知识点 |
react 函数式组件 & react其他一些总结 |
Vue基础超详细 |
前端JS也可以连点成线(Vue中运用 AntVG6) |
Vue事件处理的基本使用 |
Vue后台项目的记录 (一) |
前后端分离vue跨域,devServer配置proxy代理 |
TypeScript |
初识vuex |
vue项目安装包指令收集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 9:45:12- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |