js进阶——this和对象原型

1. this 在 JavaScript 中的应用

在 JavaScript 中,this 的值取决于函数的执行上下文和调用方式。以下是 this 在不同上下文中的行为解释:

A. 全局上下文(非严格模式)

在全局执行上下文中,this 指向全局对象(在浏览器中是 window 对象,在 Node.js 中是 global 对象)。

console.log(this); // 在浏览器中,this 指向 window 对象
B. 函数上下文

函数内部的 this 取决于函数的调用方式:

  1. 作为对象的方法调用
    当函数作为对象的方法被调用时,this 指向调用该方法的对象。

    const obj = {name: 'Alice',greet() {console.log(this.name);}
    };
    obj.greet(); // 输出 'Alice', 因为 this 指向 obj
    
  2. 作为普通函数调用
    在非严格模式下,普通函数调用中的 this 指向全局对象(浏览器中为 window),而在严格模式下,thisundefined

    function showName() {console.log(this.name);
    }// 非严格模式下
    showName(); // this 指向 window,可能会输出 undefined// 严格模式下
    'use strict';
    showName(); // this 是 undefined,调用会抛出错误
    
  3. 构造函数调用
    当使用 new 关键字调用构造函数时,this 指向新创建的对象。

    function Person(name) {this.name = name;
    }const person = new Person('Bob');
    console.log(person.name); // 输出 'Bob', this 指向新对象 person
    
  4. 箭头函数中的 this
    箭头函数不绑定自己的 this,它会捕获上下文中最近的 this 值。箭头函数常用于避免 this 在不同上下文中变化。

    const obj = {name: 'Carol',greet: function() {const innerFunc = () => {console.log(this.name); // this 来自 obj 上下文};innerFunc();}
    };obj.greet(); // 输出 'Carol'
    
C. callapplybind

这三个方法可以显式地绑定 this,并控制函数中的 this 值。

  1. call
    使用 call 可以显式指定 this,并立即调用函数。

    function greet() {console.log(this.name);
    }const person = { name: 'David' };
    greet.call(person); // 输出 'David'
    
  2. apply
    applycall 类似,但它接受的是数组作为参数。

    function introduce(age, country) {console.log(`${this.name}, ${age}, from ${country}`);
    }const person = { name: 'Eva' };
    introduce.apply(person, [25, 'USA']); // 输出 'Eva, 25, from USA'
    
  3. bind
    bind 会返回一个新函数,this 永远绑定到指定的值。

    const person = { name: 'Frank' };
    const boundFunc = greet.bind(person);
    boundFunc(); // 输出 'Frank'
    

2. 对象原型(Prototype)

JavaScript 中的原型机制是对象之间继承的核心。每个 JavaScript 对象都有一个与之相关联的原型对象(prototype),通过它可以实现属性和方法的继承。

A. 原型链

每个对象都有一个内部属性 [[Prototype]](可以通过 __proto__ 访问)。如果在对象上找不到某个属性,JavaScript 会沿着原型链向上查找,直到找到该属性或到达原型链的顶端(null)。

const animal = {speak() {console.log('Animal sound');}
};const dog = {bark() {console.log('Woof!');}
};// 将 dog 的原型设为 animal
dog.__proto__ = animal;dog.bark(); // 输出 'Woof!'
dog.speak(); // 输出 'Animal sound', 来自 animal 的原型
B. 构造函数与原型

当通过构造函数创建对象时,构造函数的 prototype 属性会成为新对象的原型。

function Person(name) {this.name = name;
}Person.prototype.greet = function() {console.log(`Hello, my name is ${this.name}`);
};const john = new Person('John');
john.greet(); // 输出 'Hello, my name is John'
C. Object.create()

Object.create() 是一个常用方法,可以创建一个新对象,并将其原型设置为指定的对象。

const parent = {speak() {console.log('I am parent');}
};const child = Object.create(parent);
child.speak(); // 输出 'I am parent', child 继承了 parent 的方法
D. 原型链继承的缺陷

由于 JavaScript 中的对象共享同一原型,当修改原型对象的属性时,所有继承该原型的对象都会受到影响。

function Animal() {}Animal.prototype.legs = 4;const dog = new Animal();
const cat = new Animal();dog.legs = 3; // 修改实例属性
console.log(cat.legs); // 输出 4,cat 的 legs 没有受到影响Animal.prototype.legs = 2; // 修改原型属性
console.log(dog.legs); // 输出 3,实例属性优先
console.log(cat.legs); // 输出 2,受原型修改影响

总结

  • this 是 JavaScript 中一个强大但有时难以理解的机制,其值取决于函数调用的方式。
  • 原型机制和原型链是 JavaScript 中对象继承的基础,构成了对象与函数的继承关系。

深入理解 this 和对象原型可以帮助你更好地掌握 JavaScript 的复杂机制,在构建复杂应用程序时写出更清晰、可维护的代码。

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

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

相关文章

华为为什么要做三折叠屏手机?

前些天我做了一条视频,关于讲华W的新的三折叠屏手机。我说我有点失望,结果引起了华W的同事的一些关注。于是,华W几位高管都跑过来,跟我解释为什么会出现这样的一个状态。 我才知道,这款手机他们其实是亏着钱在卖的。因…

C++速通LeetCode中等第1题-字母异位词分组

思路要点&#xff1a;对字符串排序&#xff0c;排序结果存放在map的key中&#xff0c;排序结果相同的字符串存放到map的value中 。 class Solution { public:string keys;vector<vector<string>> groupAnagrams(vector<string>& strs) {vector<vecto…

EECS498 Deep Learning for Computer Vision (一)软件使用指南

#最近开始学习深度学习的相关基础知识&#xff0c;记录一下相关笔记及学习成果# learning&#xff1a;building artificial systems that learn from data and experience deep learning(a set of machine learning): hierarchical learning algorithms with many "laye…

海洋大地测量基准与水下导航系列之二国外海底大地测量基准和海底观测网络发展现状(上)

海底大地控制网建设构想最先由美国斯克里普斯海洋研究所(Scripps Institution of Oceanography,SIO)提出&#xff0c;目前仅有少数发达国家具备相应技术条件。美国、日本、俄罗斯和欧盟等发达国家通过布测先进的海底大地控制网&#xff0c;不断完善海洋大地测量基准基础设施&am…

6、等级保护政策内容

数据来源&#xff1a;6.等级保护政策内容_哔哩哔哩_bilibili 信息安全产品管理与响应 等级管理 对信息系统中使用的信息安全产品实行按等级管理&#xff0c;信息安全事件应分等级响应与处置。 预测评服务由测评公司和咨询公司提供预测评服务&#xff0c;根据技术要求和测评要…

深度学习01-概述

深度学习是机器学习的一个子集。机器学习是实现人工智能的一种途径&#xff0c;而深度学习则是通过多层神经网络模拟人类大脑的方式进行学习和知识提取。 深度学习的关键特点&#xff1a; 1. 自动提取特征&#xff1a;与传统的机器学习方法不同&#xff0c;深度学习不需要手动…

前端工程化4:从0到1构建完整的前端监控平台

前言 一套完整的前端监控系统的主要部分&#xff1a; 数据上报方式数据上送时机性能数据采集错误数据采集用户行为采集定制化指标监控sdk 监控的目的&#xff1a; 一、数据上报方式 本文的方案是&#xff0c;优先navigator.sendBeacon&#xff0c;降级使用1x1像素gif图片…

Python3网络爬虫开发实战(17)爬虫的管理和部署(第一版)

文章目录 一、 Scrapyd 分布式部署1.1 了解 Scrapyd1.2 准备工作1.3 访问 Scrapyd1.4 Scrapyd 的功能1.5 ScrapydAPI 的使用 二、Scrapyd-Client 的使用2.1 准备工作2.2 Scrapyd-Client 的功能2.3 Scrapyd-Client 部署 三、Scrapyd 对接 Docker3.1 准备工作3.2 对接 Docker 四、…

Linux网络工具:用于查询DNS(域名系统)域名解析信息的命令nslookup详解

目录 一、概述 二、基本功能 1、查询域名对应的IP地址 2、查询IP地址对应的主机名 3、查询特定类型的DNS记录 三、用法 1、命令格式 2、常用选项 五、nslookup的安装 1. 打开终端 2. 更新的系统包列表 3. 安装 bind-utils 软件包 &#xff08;1&#xff09;对于Ce…

Vue点击按钮生成pdf文件/Vue点击按钮生成png图片

本次案例是vue的点击生成pdf文件和png格式的图片 一、生成pdf文件案例 看代码之前&#xff0c;我们肯定得需要看看&#xff0c;效果图是什么的啦&#xff0c;这样子才能先看看自己想要实现的效果是不是这样子的&#xff01;上效果图嘿嘿嘿~ A、实现的效果图 这是页面&#…

java intellij idea开发步骤,使用指南,工程创建与背景色字体配置,快捷键

intellij idea2021 配置背景色&#xff0c;字体大小&#xff0c;主题 快捷键

JACM23 - A New Algorithm for Euclidean Shortest Paths in the Plane

前言 如果你对这篇文章感兴趣&#xff0c;可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」&#xff0c;查看完整博客分类与对应链接。 本文关注的问题为计算几何学中的经典问题&#xff0c;即「在平面上给定一组两两不相交的多边形障碍物&#xff0c;寻找两点…

linux设置常见开机自启动命令

本文介绍了三种开机自启的方式&#xff0c;重点介绍使用systemctl的方式自启动的 方式一、修改 /etc/rc.d/rc.local 文件 /etc/rc.d/rc.local 文件会在 Linux 系统各项服务都启动完毕之后再被运行。所以你想要自己的脚本在开机后被运行的话&#xff0c;可以将自己脚本路径加到…

C++——关联式容器(4):set和map

在接触了诸如二叉搜索树、AVL树、红黑树的树形结构之后&#xff0c;我们对树的结构有了大致的了解&#xff0c;现在引入真正的关联式容器。 首先&#xff0c;先明确了关联式容器的概念。我们之前所接触到的如vector、list等容器&#xff0c;我们知道他们实际上都是线性的数据结…

51单片机——矩阵键盘

一、矩阵键盘原理图 我们发现: P17,P16,P15,P14控制行&#xff0c; P13,P12,P11,P10控制列。 所以我们如果要选择第四列&#xff0c;只需要把整个P1先给高电位1&#xff0c;再把P10给低电位0。 二、代码 P10xFF; P100; if(P170){Delay(20);while(P170);Delay(20);KeyNum…

【Linux笔记】虚拟机内Linux内容复制到宿主机的Window文件夹(文件)中

一、共享文件夹 I、Windows宿主机上创建一个文件夹 目录&#xff1a;D:\Centos_iso\shared_files II、在VMware中设置共享文件夹 1、打开VMware Workstation 2、选择需要设置的Linux虚拟机&#xff0c;点击“编辑虚拟机设置”。 3、在“选项”标签页中&#xff0c;选择“共…

【Stm32】从零建立一个工程

这里我们创建“STM32F103”系列的文件&#xff0c;基于“固件库” 1.固件库获取 https://www.st.com.cn/zh/embedded-software/stm32-standard-peripheral-libraries.html 2.使用Keil创建.uvprojx文件 前提是已经下载好了“芯片对应的固件” 3.复制底层驱动代码 将固件库下的…

LeetcodeTop100 刷题总结(一)

LeetCode 热题 100&#xff1a;https://leetcode.cn/studyplan/top-100-liked/ 文章目录 一、哈希1. 两数之和49. 字母异位词分组128. 最长连续序列 二、双指针283. 移动零11. 盛水最多的容器15. 三数之和42. 接雨水&#xff08;待完成&#xff09; 三、滑动窗口3. 无重复字符的…

嵌入式入门小工程

此代码基于s3c2440 1.点灯 //led.c void init_led(void) {unsigned int t;t GPBCON;t & ~((3 << 10) | (3 << 12) | (3 << 14) | (3 << 16));t | (1 << 10) | (1 << 12) | (1 << 14) | (1 << 16);GPBCON t; }void le…

上位机图像处理和嵌入式模块部署(linux小系统开发)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 和若干年前相比较&#xff0c;现在嵌入式linux开发要简单得多。稍微贵一点的有树莓派&#xff0c;国产的有各种水果派&#xff0c;基本上都可以按照…