当前位置: 首页 > wzjs >正文

服务器网站模板网站建设教程流程图

服务器网站模板,网站建设教程流程图,网页界面设计一般使用的分辨率,简述三只松鼠网络营销方式JavaScript 原型与原型链详解 文章目录 JavaScript 原型与原型链详解一、基础概念类1.1 什么是原型?JavaScript 中如何访问一个对象的原型?1.2 构造函数、实例对象和原型对象之间的关系是什么?1.3 prototype 和 **proto** 的区别是什么&#…

JavaScript 原型与原型链详解

文章目录

  • JavaScript 原型与原型链详解
    • 一、基础概念类
      • 1.1 什么是原型?JavaScript 中如何访问一个对象的原型?
      • 1.2 构造函数、实例对象和原型对象之间的关系是什么?
      • 1.3 prototype 和 **proto** 的区别是什么?
    • 二、原型链机制类
      • 2.1 什么是原型链?描述原型链的查找机制
      • 2.2 代码示例分析
    • 三、构造函数与实例类
      • 3.1 new 操作符执行时发生了什么?
      • 3.2 手动实现 new 操作符
        • 3.2.1apply逻辑
        • 3.2.2`result instanceof Object ? result : obj;`解决的问题
    • 四、继承与原型链类
      • 4.1 JS如何实现继承?
    • 原型链继承
    • 五、高级应用类
      • 5.1 如何修改内置对象(如 Array)的原型?这样做有什么风险?
        • 5.1.1修改内置原型
        • 5.1.2创建子类继承内置对象(ES6 Class方式)
        • 5.1.3使用Object.create创建原型链继承
      • 5.2 如何判断一个属性是对象自身的还是继承自原型链的?
    • 六、总结

一、基础概念类

1.1 什么是原型?JavaScript 中如何访问一个对象的原型?

**原型(Prototype)**是 JavaScript 实现继承的基础机制。每个 JavaScript 对象都有一个内部属性 [[Prototype]](可通过 __proto__Object.getPrototypeOf() 访问),它指向该对象的原型对象。原型对象本身也是一个普通对象,同样拥有自己的原型,这样就形成了原型链。

访问对象原型的方式

  • 对于构造函数:通过 Constructor.prototype 访问
  • 对于实例对象:
    • obj.__proto__(非标准但广泛支持)
    • Object.getPrototypeOf(obj)(标准方法)
function Person() {}
const p = new Person();// 访问构造函数的原型
console.log(Person.prototype); // 访问实例的原型
console.log(p.__proto__); 
console.log(Object.getPrototypeOf(p)); 

1.2 构造函数、实例对象和原型对象之间的关系是什么?

三者关系可概括为:

  1. 构造函数:用于创建对象的函数,拥有 prototype 属性
  2. 原型对象:通过 Constructor.prototype 访问,包含共享属性和方法
  3. 实例对象:通过 new Constructor() 创建,其 __proto__ 指向构造函数的原型

关系图示:

构造函数 (Person)├── prototype (原型对象)│     ├── constructor (指回构造函数)│     └── 共享属性和方法└── 实例化└── 实例对象 (p)└── __proto__ (指向原型对象)

关键点:

  • 构造函数的 prototype 属性指向原型对象
  • 原型对象的 constructor 属性指回构造函数
  • 实例对象的 __proto__ 指向构造函数的原型对象

1.3 prototype 和 proto 的区别是什么?

特性prototype__proto__
所属对象函数对象(包括函数)
作用为构造函数定义共享属性和方法指向对象的原型,形成原型链
是否标准否(非标准但广泛支持)
访问方式Constructor.prototypeobj.__proto__Object.getPrototypeOf(obj)
用途场景实现继承和共享方法属性查找机制

关键区别

  • prototype 是函数特有的属性,用于实现基于原型的继承
  • __proto__ 是对象实例的属性,指向其构造函数的原型对象

二、原型链机制类

2.1 什么是原型链?描述原型链的查找机制

原型链是由对象的 __proto__ 链接形成的链条结构,它允许对象访问其原型上的属性和方法,直到 Object.prototype.__proto__(值为 null)为止。

原型链查找机制

  1. 访问对象属性时,首先在对象自身查找
  2. 如果自身不存在该属性,则通过 __proto__ 查找其原型对象
  3. 继续沿原型链向上查找,直到找到属性或到达原型链顶端(null
  4. 如果最终未找到,则返回 undefined

这种机制实现了 JavaScript 的继承和属性共享。

2.2 代码示例分析

function Person() {}
Person.prototype.name = "Alice";let p = new Person();
console.log(p.name); // "Alice"
console.log(p.hasOwnProperty("name")); // false

执行过程解析

  1. p.name 访问时:
    • 首先在 p 对象自身查找 name 属性 → 未找到
    • 通过 p.__proto__ 查找 Person.prototype → 找到 name: "Alice"
    • 返回 "Alice"
  2. p.hasOwnProperty("name")
    • hasOwnProperty 是检查属性是否为对象自身的属性
    • name 实际存在于 Person.prototype 上,而非 p 对象自身
    • 返回 false

三、构造函数与实例类

3.1 new 操作符执行时发生了什么?

new 操作符创建实例时,背后执行了以下步骤:

  1. 创建一个新的空对象 {}
  2. 将新对象的 __proto__ 指向构造函数的 prototype 属性
  3. 将构造函数的 this 绑定到新对象,并执行构造函数
  4. 如果构造函数返回一个对象,则返回该对象;否则返回新创建的对象

完整过程示例

function Person(name) {this.name = name;
}const p = new Person("Alice");

等价于:

function myNew(Constructor, ...args) {// 1. 创建空对象let obj = {};// 2. 设置原型链obj.__proto__ = Constructor.prototype;// 3. 绑定this并执行构造函数let result = Constructor.apply(obj, args);// 4. 返回结果(优先返回对象,否则返回新对象)return result instanceof Object ? result : obj;
}const p = myNew(Person, "Alice");

3.2 手动实现 new 操作符

function myNew(Constructor, ...args) {// 1. 创建一个新对象,并将其原型指向构造函数的prototypelet obj = Object.create(Constructor.prototype);// 2. 调用构造函数,将this绑定到新对象,args是一个数组let result = Constructor.apply(obj, args);// 3. 如果构造函数返回了一个对象,则返回该对象;否则返回新对象return result instanceof Object ? result : obj;
}
3.2.1apply逻辑

apply(thisArg,argsArray) 接收 两个参数

  1. thisArg(必需):函数运行时绑定的 this 值。
  2. argsArray(可选):一个数组或类数组对象,包含传递给函数的参数列表。如果省略或为 null/undefined,则相当于传递空数组。

argsArray 的核心作用是解耦 myNew 和构造函数 Constructor 之间的参数关系

  1. myNew 不需要关心具体有多少参数,只需将所有额外参数打包到 args 数组中。
  2. Constructor 可以自由定义自己需要的参数,通过 this 接收并处理。
3.2.2result instanceof Object ? result : obj;解决的问题

作用:处理构造函数 Constructor 的返回值,确保最终返回的对象符合预期

在 JavaScript 中,构造函数(通过 new 调用的函数)可以显式返回一个值。这个返回值可以是:

  1. 一个对象(包括数组、函数、普通对象等)。
  2. 一个原始值(如 numberstringbooleannullundefined)。

如果构造函数返回一个对象,new 操作符会忽略默认创建的实例对象,直接返回这个指定的对象;如果返回原始值,则忽略返回值,仍然返回默认创建的实例对象。

示例:构造函数返回对象 vs 原始值
// 情况1:构造函数返回对象
function Person1() {return { name: "Bob" }; // 返回一个新对象
}
const p1 = new Person1();
console.log(p1); // { name: "Bob" }(不是 Person1 的实例)// 情况2:构造函数返回原始值
function Person2() {return 123; // 返回原始值
}
const p2 = new Person2();
console.log(p2); // Person2 的实例(不是 123)

四、继承与原型链类

4.1 JS如何实现继承?

原型链继承

核心:将子类的原型指向父类的实例

JavaScript 中通过原型链继承实现继承的基本模式:

function Parent() {this.parentProperty = "Parent Value";
}Parent.prototype.parentMethod = function() {console.log("Parent Method");
};function Child() {this.childProperty = "Child Value";
}// 关键步骤:将Child的原型指向Parent的实例
Child.prototype = new Parent();const c = new Child();
console.log(c.parentProperty); // "Parent Value"
c.parentMethod(); // "Parent Method"

继承关系图示

Child实例 (c)├── __proto__ → Child.prototype (Parent的实例)├── __proto__ → Parent.prototype├── constructor → Parent└── parentMethod└── childProperty (来自Child构造函数)

注意:这种继承方式存在一些问题(如引用类型共享、无法向父类构造函数传参等),现代开发更推荐使用 ES6 的 classextends 语法。

五、高级应用类

5.1 如何修改内置对象(如 Array)的原型?这样做有什么风险?

5.1.1修改内置原型

修改方式示例

// 添加自定义方法到Array原型
Array.prototype.customMethod = function() {console.log("This is a custom method");
};const arr = [1, 2, 3];
arr.customMethod(); // "This is a custom method"

潜在风险

  1. 全局污染:修改内置原型会影响所有使用该内置对象的代码
  2. 命名冲突:可能与未来 JavaScript 版本新增的方法名冲突
  3. 兼容性问题:可能导致与其他库或框架的不可预期交互
  4. 维护困难:使代码行为变得不可预测,增加调试难度

最佳实践

  • 避免直接修改内置原型
  • 如需扩展功能,考虑使用工具函数或创建子类
  • 如果必须修改,添加前缀以减少冲突风险(如 myCustomMethod
5.1.2创建子类继承内置对象(ES6 Class方式)

这是最推荐的方式,既扩展了功能,又不会影响原生对象。

1. 基础继承示例

// 创建继承自Array的自定义类
class CustomArray extends Array {// 添加自定义方法customSum() {return this.reduce((acc, val) => acc + val, 0);}// 可以添加更多自定义方法customMax() {return Math.max(...this);}
}// 使用示例
const arr = new CustomArray(1, 2, 3, 4);
console.log(arr.customSum()); // 输出: 10
console.log(arr.customMax()); // 输出: 4
console.log(arr instanceof Array); // true (仍然属于Array类型)
5.1.3使用Object.create创建原型链继承

更底层的实现方式,不使用ES6 class语法。

// 创建基于Array的新对象
const EnhancedArray = function(...items) {const arr = [...items];return Object.setPrototypeOf(arr, EnhancedArray.prototype);
};// 设置原型链
EnhancedArray.prototype = Object.create(Array.prototype);
EnhancedArray.prototype.constructor = EnhancedArray;// 添加自定义方法
EnhancedArray.prototype.customSum = function() {return this.reduce((acc, val) => acc + val, 0);
};// 使用示例
const arr = EnhancedArray(1, 2, 3);
console.log(arr.customSum()); // 输出: 6
console.log(arr instanceof Array); // true

5.2 如何判断一个属性是对象自身的还是继承自原型链的?

判断方法

  1. hasOwnProperty() 方法:

    • 只检查对象自身的属性,不检查原型链
    const obj = { a: 1 };
    console.log(obj.hasOwnProperty('a')); // true
    console.log(obj.hasOwnProperty('toString')); // false
    
  2. Object.getOwnPropertyNames()

    • 返回对象自身的所有属性名(不包括原型链)
    const obj = { a: 1, b: 2 };
    console.log(Object.getOwnPropertyNames(obj)); // ["a", "b"]
    
  3. in 操作符:

    • 检查属性是否存在于对象或其原型链中
    const obj = { a: 1 };
    console.log('a' in obj); // true
    console.log('toString' in obj); // true
    

综合示例

function checkProperty(obj, prop) {if (obj.hasOwnProperty(prop)) {console.log(`${prop} 是对象自身的属性`);} else if (prop in obj) {console.log(`${prop} 是继承自原型链的属性`);} else {console.log(`${prop} 不是对象的属性`);}
}const obj = { a: 1 };
checkProperty(obj, 'a'); // "a 是对象自身的属性"
checkProperty(obj, 'toString'); // "toString 是继承自原型链的属性"
checkProperty(obj, 'b'); // "b 不是对象的属性"

六、总结

JavaScript 的原型和原型链机制是其面向对象编程的核心,理解这些概念对于掌握 JavaScript 至关重要:

  1. 原型是对象间共享属性和方法的机制
  2. 原型链实现了属性的查找和继承
  3. 构造函数、实例和原型三者构成了 JavaScript 对象系统的基础
  4. new 操作符通过特定步骤创建实例并建立原型链
  5. 原型链继承是 JavaScript 实现继承的主要方式
  6. 谨慎操作内置原型,避免潜在风险
  7. 准确判断属性来源对调试和维护非常重要

文章转载自:

http://9GgvJK5R.nzxdz.cn
http://FCuaqAzR.nzxdz.cn
http://voZsxjMl.nzxdz.cn
http://sD8B38V8.nzxdz.cn
http://Qm2miefg.nzxdz.cn
http://YHu01hUx.nzxdz.cn
http://DNm2m5CN.nzxdz.cn
http://c5zUtgIs.nzxdz.cn
http://9wMjT4Dc.nzxdz.cn
http://PGECKy0g.nzxdz.cn
http://4Uvy3mBi.nzxdz.cn
http://3G163fqK.nzxdz.cn
http://WueByWTn.nzxdz.cn
http://i1nfENqY.nzxdz.cn
http://gFzcPU3h.nzxdz.cn
http://VI0c2UFJ.nzxdz.cn
http://SzRey0GO.nzxdz.cn
http://9k18wucL.nzxdz.cn
http://sYDelGde.nzxdz.cn
http://AlN3Ogrh.nzxdz.cn
http://CDH7PjJ2.nzxdz.cn
http://1oJWcKbM.nzxdz.cn
http://VNuiI1eb.nzxdz.cn
http://fuRxw3z1.nzxdz.cn
http://TzyC4BlA.nzxdz.cn
http://NYA2DOUb.nzxdz.cn
http://EAivsQyd.nzxdz.cn
http://TFgDmXsE.nzxdz.cn
http://sHCXA0b7.nzxdz.cn
http://a33fO5Lr.nzxdz.cn
http://www.dtcms.com/wzjs/644029.html

相关文章:

  • wordpress 网站播放器插件怎么免费做一个网站
  • 高要住房和城乡建设局网站自助网站建设哪家效益快
  • 江苏建发建设项目咨询有限公司网站台前做网站的公司
  • 电商网站 费用百度wordpress插件下载
  • 国家职业资格证书网站wordpress网页没法评论
  • 建站网站官方网站建设兼职合同
  • 购物网站建设与开发做一个公司网站
  • 爱站工具包的模块有哪些苏州市网站建设培训
  • 免费ppt成品网站深圳网站建设制作公司
  • 福田网站优化seo课程培训中心
  • 关于化妆品的网页设计网站seo设计
  • 商城平台网站开发深圳绵阳网站托管
  • 网站页面设计网页说明安卓系统
  • 网站开发税率多少钱河南省建设部官方网站
  • 精仿源码社区网站源码谷歌seo工具
  • 怎么做网站广告位android最新版本
  • 网站建设中 模板下载成都 网站设计
  • 怎么做兼职网站吗做外贸常用那几个网站
  • 刷赞抖音推广网站个人简历模板下载 免费完整版
  • 餐饮企业网站模板十大教育培训机构排名
  • 自己做的网站慢是什么原因小程序开发文档微信小程序
  • 东莞企业网站建设方案信用中国 网站截图怎么做
  • 保险公司官方网站济南网站seo
  • 菏泽网站建设菏泽为wordpress添加虚拟用户权限
  • 深圳华南城网站建设南京响应式网站制作
  • 做游戏类型的网站的好处建筑网站免费
  • 网站建设好找工作温州市永嘉上塘建设局网站
  • 人才招聘网站模板生活信息网站如何推广
  • 重庆哪里可以做网站的湖南自考网站建设与管理
  • 实训网站建设的心得总结动漫制作专业需要学什么