JS高级(二):继承、数组的一些api、Object.defineProperty()、call、apply、bind

news2025/1/18 4:39:36

JavaScript高级(二)

  • 一、继承
    • 1.call方法改变this指向
    • 2.构造函数中模拟类的super实现属性继承
    • 3.构造函数借助原型对象实现方法继承
    • 4.类的本质
  • 二、ES5几个新增方法
    • 1.数组`forEach()`
    • 2.数组`filter()`
    • 3.数组`some()`
    • 4.字符串`trim()`
  • 三、Object.definProperty()
  • 四、改变this指向的三个函数
    • 1.call()
    • 2.apply()
    • 3.bind()

一、继承

1.call方法改变this指向

call方法第一个参数可以改变函数的this指向,后面的参数和正常调用函数传参一样

let obj = {
    name: 'dj'
}
function fn(x,y) {
    console.log('奥里给');
    console.log(this);  //obj
    console.log(x + y)
}
fn.call(obj,1,2);  //奥里给 obj 3

2.构造函数中模拟类的super实现属性继承

在ES6之前是没有类的,只有构造函数(其实类就是构造函数,类的本质就是一个函数),那么子构造函数如何继承父构造函数的属性呢?
答案是借助call方法,改变子构造函数中的this指向。

//模拟类中的super实现继承
function Father(name, age) {
    this.name = name;
    this.age = age;
}

function Son(name, age, score) {
    //调用一下父构造函数,并让它里面的this指向子构造函数
    Father.call(this, name, age);//调用并传参过去
    //相当于给子实例添加name和age属性

    this.score = score;  //再添加子构造函数自身的属性
}

let zzy = new Son('zzy', 18, 100);
console.log(zzy.name, zzy.age, zzy.score); //zzy 18 100

3.构造函数借助原型对象实现方法继承

还是上面那个案例。父的原型对象上定义一个方法,如果子想要调用这个方法,怎么办?
答案是利用原型,如果直接Son.prototype = Father.prototype行吗?这是一个浅拷贝,这样的话子和父原型对象地址一样,如果子添加自有方法,父也会添加,不合理。

但是如果Son.prototype = new Father();就可以,这是一个深拷贝,这样的话子的原型对象就可以通过父的实例指向父的原型对象,解决上面的问题。不过bug是子原型对象的constructor也会指向父,需要手动改为子。

//2.1继承父构造函数的方法
	Father.prototype.speak = function () {
	    console.log('hello world');
	}
	//这样不行,如果子添加自有方法,父也会添加,因为他们指向同一个地址
	// Son.prototype = Father.prototype; 
	Son.prototype = new Father();  //这样就可以了
	//但是如果这样的话,Son.prototype.constructor就指向Father了,我们要改回来
	Son.prototype.constructor = Son;

    zzy.speak(); //hello world
    console.log(Son.prototype.constructor);//修改前:Father  后:Son

在这里插入图片描述

4.类的本质

实际上类的本质就是一个函数,ES6的类其实就是ES5构造函数的语法糖。因为构造函数实现继承实在麻烦,而类只用个extends关键字就欧了。

类也有原型对象,类的实例也有__proto__,所以类tmd就是构造函数。

二、ES5几个新增方法

1.数组forEach()

遍历数组,可以改变原数组(复杂数据类型),返回undefined,这个api中写return无法终止循环。
同样可以实现遍历的map()不会改变原数组,会生返回一个新数组

	let arr = [12, 2, 34];
	arr.forEach(function (el, index, array) {
	    console.log('每个数组元素' + el);
	    console.log('每个数组元素的索引' + index);
	    console.log('数组本身' + array);
	})

什么时候forEach()不能改变原数组?当数组元素为简单数据类型时(操作el不会变,操作arr[index]就会变,奇怪),而复杂数据类型如果修改了里面的属性,原数组就会改变

//1.简单数据类型,不会改原数组
let arr = [12, 2, 34];
arr.forEach(function (el, index, array) {
    console.log('每个数组元素' + el);
    console.log('每个数组元素的索引' + index);
    console.log('数组本身' + array);
    el = el + 100;
    console.log(array,'不变');  //[12, 2, 34]'不变'
    array[index] = array[index] + 100;
    console.log(array,'变了'); //[112, 12, 134]'变了',这样就可以改变原数组,奇怪
})
console.log(arr);  //[112, 12, 134]变了

这是因为简单数据类型存储在栈中,复杂数据类型在堆中,forEach如果修改复杂数据类型,相当于拿它们的地址来修改里面的属性。换句话说,forEach操作时是对原数组的一个浅拷贝

//2.复杂数据类型,会改原数组
let arr2 = [{age:18}, {age:2}, {age:34}];
arr2.forEach(function (el, index, array) {
    el.age = 20;
})
console.log(arr2); //[{age:20}, {age:20}, {age:20}]变了

for循环可以改变原数组

for (let i = 0; i < arr.length; i++) {
    arr[i] = arr[i] +100;
}
console.log(arr,'11'); // [112, 102, 134] '11'

2.数组filter()

筛选数组元素,返回一个新数组。
参数:(每个元素,索引号,数组本身)

let arr = [23, 53, 4, 3, 12];
//使用filter筛选小于20的数字
let newArr = arr.filter(function (el, index, array) {
    // 参数:每个元素,索引号,数组本身
    return el > 20; //把为true的筛出来
})
console.log(newArr); //[23,53]

3.数组some()

查找数组中有没有满足条件的元素,如果找到第一个,就不再往后执行,这也导致some的效率比其他的更高一些,找到了直接return true就终止循环了。
参数:(每个元素,索引号,数组本身)
filter差不多,区别在于some返回的是一个布尔值

let arr = [23, 53, 4, 3, 12];
let hasEl = arr.some( (el) => {
    return el === 4;
})
console.log(hasEl); //true

4.字符串trim()

去除字符串两边的空格(只去首尾),返回一个新的字符串。如果完了去看todolist,里面用过这样的骚操作。

let str = '  zzy   ';
let newStr = str.trim();
console.log(str);
console.log(newStr);

在这里插入图片描述

三、Object.definProperty()

这个很重要,vue中双向绑定的原理就是这个
在这里插入图片描述
enumerablewritableconfigurable这些属性,只有新增的才会默认为false,对象本来就有的都是true

let number = 18;
let person = {
    name: 'zzy',
    sex: '男',
    // age: number
}

Object.defineProperty(person, 'age', {
    //     value: 18,
           enumerable: true,  //控制属性是否可以被遍历,默认值是false
    //     writable: true,  //控制属性是否可以被修改,默认值是false
    //     configurable: true  //控制属性是否可以被删除,默认值是false

    //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
    get() {
        console.log('有人读取age了');
        return number;
    },

    //当有人修改person的age属性时,set函数(setter)就会被调用,且返回值就是age的值
    set(val) {
        console.log('有人修改age的值,' + val);
        number = val;
    }
})
console.log(person); //{name: 'zzy', sex: '男'}
console.log(Object.keys(person)); // ['name', 'sex', 'age']

四、改变this指向的三个函数

这三个函数都可以改变函数内部的this指向

1.call()

特点:
1、参数(this指向谁,参数1,参数2…)
2、立即调用

 let obj = {
     name: 'dj'
 }
 function fn(x, y) {
     console.log(this); 
     console.log(x + y)
 }
 fn.call(obj, 1, 2);  //obj 3

2.apply()

特点:
1、第二个参数是一个伪数组:( this指向谁,[ ] )
2、立即调用
3、数组传过去会把元素取出来展示,每一个形参对应数组的每一项

  function fn2(el1,el2) {
      console.log(this);  //obj
      console.log(el1,el2);  //字符串'zzy' 'ht'
  }
  fn2.apply(obj,['zzy','ht']);  

应用:利用apply求数组中的最大值(apply传过去的数组会被拆开)

 let arr = [23, 143, 2, 1, 25];
 let max = Math.max.apply(null, arr); //不用改this所以写null,严格模式下写Math
 console.log(max); //143

 console.log(Math.max(...arr)); //用这个更简单

3.bind()

特点:
1、参数(this指向谁,参数1,参数2…)
2、不会立即调用
3、返回一个改变this指向后的原函数拷贝

function fn3(x, y) {
    console.log(this);
    console.log(x + y)
}
let newFn = fn3.bind(obj, 1, 2);  //不会立即调用
newFn(); //obj 3

bind应用:点击按钮禁用,3秒后取消禁用。bind可以改变函数的this指向,但不立即执行。看完这个,再去对比ES6中的箭头函数,就知道箭头函数有多方便了。

let btn = document.querySelector('button');
btn.addEventListener('click', function() {
    this.disabled = true;
    setTimeout(function() {
        this.disabled = false;  //把this从window改成btn
    }.bind(this),3000)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/10029.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于STM32结合CubeMX学习Free-RT-OS的源码之深入学习软件定时器实现过程

概述 关于在CUBEMX上的配置 介绍 软件定时器基于硬件定时器实现。 软件定时器允许设置一段时间&#xff0c;当设置的时间到达之后就执行指定的功能函数&#xff0c;被定时器 调用的这个功能函数叫做定时器的回调函数。回调函数的两次执行间隔叫做定时器的定时周期&#xff0c;…

什么是需求分析,如何进行需求分析?

目录 前言 需求分析在分析什么 如何看待产品原型设计 技术同学培养产品意识 如何应对需求变更问题 总结 重点&#xff1a;配套学习资料和视频教学 前言 这篇文章&#xff0c;我会将软件工程中关于需求分析相关的知识进行总结梳理&#xff0c;并以自己理解的方式进行阐述…

iNFTnews|风口之上,耐克推出的web3平台.SWOOSH能否引领市场?

本周一&#xff0c;著名的体育运动品牌耐克宣布&#xff0c;公司将进一步进军Web3&#xff0c;并将发布一个旨在通过旗下的数字可穿戴设备吸引用户的新平台——.SWOOSH。 耐克表示&#xff0c;.SWOOSH将成为Web3教育的资源库&#xff0c;以及购买和交易虚拟运动鞋或运动衫等数…

Oracle SQL执行计划操作(3)——物化视图相关操作

3. 物化视图相关操作 该类操作与SQL语句执行计划中访问物化视图数据的路径和方式相关,主要包括物化视图访问类相关操作。根据不同的具体SQL语句及其他相关因素,如下各操作可能会出现于相关SQL语句的执行计划。 1)MAT_VIEW ACCESS FULL 对物化视图(Materialized View)直…

培训学校的教务管理系统存在的问题有哪些?

教务管理在培训学校管理里面占据不可或缺的地位。随着计算机、网络、大数据、人工智能等技术的发展&#xff0c;国家对智慧校园的重视&#xff0c;促进了培训学校教务管理信息化与智慧化建设。然而&#xff0c;随着科技进步速度不断加快&#xff0c;教育改革步伐的不断加大&…

解决:将Ubuntu系统打包成ios镜像并制作U盘系统

将Ubuntu系统打包成ios镜像并制作U盘系统一、安装 Systemback二、将创建的.sblive镜像文件转为.iso格式三、写入U盘进行安装四、制作系统U盘一、安装 Systemback Currently supported Ubuntu releases: - 14.04.X LTS - 15.04 - 15.10 - 16.04.X LTS - 16.10Systemback的作者在…

linux的基本指令(中)

文章目录1.man指令1.安装2.用法3.man数字1. printf函数的查询2.cp指令1.cp 文件1.拷贝到当前目录2.拷贝到 其他目录中3. 拷贝到上一级目录2.cp 目录1.返回上一级目录3. mv指令1.剪切2. 文件的重命名4. cat指令1.显示文件的全部内容并且不可以修改2.cat -n指令3. cat -s 指令5. …

6张思维导图,搞定项目管理!(PMP项目管理可用)

工作中&#xff0c;我们最常遇到的就是大大小小的工作项目。项目要怎么做&#xff0c;才能100%达成目标呢&#xff1f; 小哈总结了6组项目管理思维导图。只要从五大阶段掌握诀窍&#xff0c;用项目管理的思维去管理工作&#xff0c;工作就能有条不紊按预期达到目标&#xff0c…

GitHub Codespaces 安装 .NET 7

本文主要介绍如何在 GitHub Codespaces 这个云上 IDE 环境中安装 .NET 7 背景 GitHub 的 Codespaces 可以让我们随时随地编写代码&#xff0c;一些简单的修改也非常方便快捷。特别是 .NET 7 发布后&#xff0c;一些可以直接升级的小项目只需要更改配置就可以了&#xff0c;我们…

EN 14915实木镶板和包层—CE认证

实木镶板和包层CE认证&#xff08;欧盟强制认证&#xff09;&#xff0d;简介 在欧盟市场“CE”标志属强制性认证标志&#xff0c;以表明产品符合欧盟《技术协调与标准化新方法》指令的基本要求。这是欧盟法律对产品提出的一种强制性要求。 在实木镶板和包层上加贴CE标志不但可…

Active Directory报表计划

ADManager Plus的“计划报表”功能是一个独有模块&#xff0c;可使报表生成实现自动化。IT管理员现在可为任何所需的时间段&#xff08;从一个小时到一个月&#xff09;计划报表。因而&#xff0c;计划功能可提供一致、准确的报表交付&#xff0c;而不会产生任何麻烦和费用。本…

【ESP32_8266_WiFi (十三)】ESP8266自动配网 – WiFiManager库使用说明

文章目录ESP8266自动配网 – WiFiManager库使用说明1 WiFiManager库使用说明1.1 WiFi配置流程1.2 WiFi配置示例程序1.2.1 预备程序 – 清理ESP8266储存的WiFi连接信息1.2.2 WiFiManager网络配置示例程序1.2.3 WiFiManager网络配置测试2 WiFiManager库汉化和定制说明2.1 WiFiMan…

Spring(十)- Spring Bean的基本注解

文章目录一、Spring Bean的基本注解一、Spring Bean的基本注解 Spring除了xml配置文件进行配置之外&#xff0c;还可以使用注解方式进行配置&#xff0c;注解方式慢慢成为xml配置的替代方案。我们有了xml开发的经验&#xff0c;学习注解开发就方便了许多&#xff0c;注解开发更…

调节自噬的小分子化合物

自噬? 生物体需要通过不断合成和降解物质来维持自身的内稳态&#xff08;Homeostasis&#xff09;。细胞内物质的降解主要通过两种途径进行&#xff1a;泛素化蛋白酶体途径&#xff08;Ubiquitin-proteasome system, UPS&#xff09;和自噬溶酶体途径&#xff08;Autophagy-ly…

06 数组

本文仅作为个人笔记 数组 数组的引入 import java.util.Scanner; public class TestArray01{public static void main(String[] args){//功能&#xff1a;键盘录入是个学生的成绩&#xff0c;求和&#xff0c;求平均数&#xff1a;//定义一个求和的变量&#xff1a;int sum …

GoF之代理模式

GoF之代理模式 1、 对代理模式的理解 生活场景1&#xff1a;牛村的牛二看上了隔壁村小花&#xff0c;牛二不好意思直接找小花&#xff0c;于是牛二找来了媒婆王妈妈。这里面就有一个非常典型的代理模式。牛二不能和小花直接对接&#xff0c;只能找一个中间人。其中王妈妈是代…

Linux | 磁盘结构 | 文件系统认识 | inode | 软硬链接

文章目录磁盘物理结构的认识磁盘的分区inode和文件数据之间的映射文件名和inode之间的映射文件知道自己的inode号吗&#xff1f;文件的软硬链接硬链接数磁盘物理结构的认识 &#xff08;图片来自于网络&#xff09;一个磁盘由许多盘片构成&#xff0c;每个盘片上有着许多磁道&a…

SAP Table function 执行报错 code CX_SQL_EXCEPTION feature not supported 该如何分析

我的知识星球里有朋友提问&#xff1a; 我的场景是cds 调用 table function, table function 调用 amdp 然后报错: code:CX_SQL_EXCEPTION message: feature not supported.Contains predicates only supported when table function is unfolded? 请问这个是什么意思&#xf…

使用分贝的波动大小将声音数据降维成字符

🍿*★,*:.☆欢迎您/$:*.★* 🍿 目录 背景 正文 总结 背景描述

【高速数字化仪应用案例系列】虹科数字化仪在大型物理实验领域的应用

大型物理实验应用 了解物质和自然力量的使命推动着在物理学科领域进行更大&#xff0c;更复杂的实验。为了做到这一点&#xff0c;科学家和工程师正在建造比以往更大&#xff0c;更强大&#xff0c;更灵敏的机器和仪器。例如&#xff0c;天文学家正在使用不断膨胀的电磁波谱部…