图说原型链

本文深入浅出地介绍了JavaScript中的原型链机制,通过实例演示了如何使用构造函数和原型对象,并解释了对象查找属性的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

说到原型链,javascript 中,万物皆对象,而 javascript 规定,所有对象都有自己的原型对象(prototype) ,一方面,任何对象都可以充当其他对象的原型,另一方面,原型(prototype)也是对象,也拥有自己的原型,因此形成的链就是原型链。到这里我就啰嗦几句,javascript 的设计者Brendan Eich在设计这门语言之初,只是想它在网页上实现简单的交互,比如表单提交前进行简单的校验,所以没有设计类与继承的概念,因为觉得这样的话太正式了,但是受时代的影响,javascript里面都是对象,虽然没有继承,但是也要一种机制,把这些对象联系起来,这种机制就是原型链。话不多说,上图

图解

  • 假设有一个内存空间(正方形表示),这片内存里放了一个构造函数Dog(用三角形表示)
function Dog () {
    this.leg = 4;
    this.bray = function () {
        alert('wangwang');
    }
}

图片描述

  • 设置构造函数的原型函数(prototype)
Dog.prototype = {
    spacies: 'dog'
}
console.log(Dog.prototype)    // {spacies: 'dog'}

那么,就会在另外一个内存中存储 Dog 的 prototype 对象(用椭圆形表示),如图所示,构造函数的protype指向它的原型
图片描述

  • 现在我们用 构造函数 Dog 来创建对象 dog1, dog2, ...
var dog1 = new Dog();
dog1.name = '大黄';
dog1.color = 'yellow';

var dog2 = new Dog();
dog2.name = '小黑';
dog2.color = 'black';

console.log(dog1.name)     // 大黄
console.log(dog2.name)     // 小黑
console.log(dog1.spacies)  // dog
console.log(dog2.spacies)  // dog
console.log(dog1.constructor === Dog)   // true

图片描述

可以看到由构造函数创造的对象dog1,dog2,他们的constructor指向构造函数Dog,而他们的__proto__指向Dog的prototype,而且当调用对象的一个属性或方法时,首先会找对象本身的属性或方法,找不到时,会找该对象的__proto__对象(也就是构造函数的prototype对象),以此类推,会找原型链上所有对象有没有该属性,如果找到则返回该属性的值,如果还是找不到则返回undefined
另外可以看出来dog1,dog2,...的__proto__指向同一块内存地址,这样设计是为了节省内存资源,不用每次创建都存储他们相同的属性,当修改dog1的__proto__时,dog2的__proto__也会改变

dog1.__proto__.spacies = 'animal'; // 或者Dog.prototype.spacies = 'animal'
console.log(dog2.spacies)    // animal
  • 上面也说到了,每一个对象都有自己的__proto__,而作为构造函数Dog的prototype对象,也会有自己的对象原型,以此类推,原型链的顶端是一个null,如图的红线串起来的链就是原型链

图片描述

额,来一个句话收尾吧,这是我自己对原型连的理解,欢迎探讨

参考

Javascript继承机制的设计思想
prototype 对象

### SQL 关联查询与子查询的概念 #### 视图简介 视图本质上是一个保存在数据库中的查询语句,它代表了一个虚拟的表。当访问视图时,实际上是在执行该视图所定义的基础查询语句[^1]。 #### 子查询概念 子查询是指嵌套在一个更大查询内部的小型查询。这些小型查询可以位于`SELECT`、`FROM`或`WHERE`子句中,并且通常用于提供过滤条件或其他操作所需的值。例如,在给定的成绩表例子中,通过子查询计算特定科目的平均分数并将其作为外部查询的一部分来筛选高于此均值的学生记录[^2]。 ```sql select * from scores as s where score > ( select avg(score) from scores where cid = s.cid ) and Sid BETWEEN 1 and 6; ``` #### 联接查询概述 关联查询涉及多个表格之间基于某些共同列的数据组合方式。最常见的是使用`JOIN`语法实现不同类型的连接: - **内连接 (`INNER JOIN`)** 只返回两个表中共有的匹配行。 - **左外连接 (`LEFT OUTER JOIN`) 和右外连接 (`RIGHT OUTER JOIN`)** 返回左边/右边表的所有记录以及另一边表中存在的对应项;如果另一侧无匹配,则填充NULL值。 - **全外连接 (`FULL OUTER JOIN`)** 结合了左右两侧所有的数据,即使它们不相交也会显示出来,对于缺失的部分则用null代替。 此外还有自然连接(`NATURAL JOIN`)这种特殊的等值连接形式,会自动识别两张表间具有相同名称的字段来进行比较[^3]。 ```sql select * from emp natural join dept; ``` #### 子查询 VS 联接查询对比分析 | 特征 | 子查询 | 联接查询 | |--| | 定义 | 嵌入到另一个SQL命令内的独立查询 | 处理来自一个以上的关系对象(即表)的信息 | | 使用场景 | 当需要先处理一部分逻辑再应用于整体时 | 需要跨多张表检索信息 | | 性能 | 对于复杂情况可能较慢 | 如果索引得当的话性能较好 | | 易读性和维护性 | 更加直观易懂 | 表达更复杂的业务关系 | #### 图解明 为了更好地理解这两种技术的区别,请考虑下面这个简单的Venn图表示法: ![image](https://example.com/image.png) 在这个假设的例子中,“A”和“B”分别代表不同的实体集(比如员工和部门)。橙色区域展示了两种方法如何交互作用以提取所需的结果集: - 左边部分展示了一种典型的子查询应用场景——我们首先确定某个属性满足一定标准的对象集合(如高薪雇员),然后再与其他相关资源建立联系; - 右边则是关于联接查询的一个实例,这里强调的是直接将两个结构化存储单元按照预设规则结合起来的过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值