JavaScript之Object原型方法

本文探讨了JavaScript中的对象原型,重点介绍了Object原型上的属性和函数,包括`__proto__`、`propertyIsEnumerable`、`hasOwnProperty`等。同时,详细解析了`defineProperty`方法,阐述了属性的可写、可配置和可枚举三个特性,并给出了使用示例。此外,还提及了Object的其他实用函数,建议查阅Mozilla官方文档以获取更多详情。

Object

在JS 中,对象都是有原型的,甚至原型链。不过最终都是指向一个最初的原型,即 Object 对象的原型。那这个原型里都有啥呢?下面一起来看下,首先在浏览器控制台输入 {},我们知道这是创建一个对象。


从上面的图片我们发现对象的 原型属性 __proto__ 下面有 13 个属性或者函数(这里我用的是Chrome,不同浏览器可能不一样)。

原型函数

下面一一看下:

函数作用说明
obj.__defineGetter__(prop, func)将一个函数绑定在当前对象的指定属性上,当那个属性被读取时,你所绑定的函数就会被调用Web标准已废弃
obj.__defineSetter__(sprop, func)将一个函数绑定在当前对象的指定属性上,当那个属性被赋值时,你所绑定的函数就会被调用Web标准已废弃
obj.__lookupGetter__(sprop)返回当前对象上指定属性的属性读取访问器函数(getter),即上面设的函数Web标准已废弃
obj.__lookupSetter__(sprop)返回一个对象的某个属性上绑定了 setter (设置器)的钩子函数的引用Web标准已废弃
obj.toString()返回一个表示该对象的字符串
obj.toLocaleString()返回调用 toString() 方法的结果
obj.valueOf()返回值为该对象的原始值
obj.constructor即 Object的构造函数
obj.propertyIsEnumerable(prop)判断属性是否是当前对象可枚举的自身属性
prototypeObj.isPrototypeOf(object)用于测试一个对象是否存在于另一个对象的原型链上
obj.hasOwnProperty(prop)判断对象是否具有指定的属性作为自身(不继承)属性

例子

下面通过一些代码来说明各个函数的作用。

var obj = {};

var readCallback = function() {
	console.log('name was read');
}

obj.__defineGetter__('name', readCallback);

console.log(obj.name);// 读取 name 属性后,会调用上面的函数。

var reassignCallback = function(val) {// 新值会作为参数传进来
	console.log('name was assigned again with : ' + val);
};

obj.__defineSetter__('name', reassignCallback);

obj.name = 'name';// 修改 name 属性后,会调用上面的函数。

var lookupGetFun = obj.__lookupGetter__('name');// 返回上面我们设置的 Getter函数
console.log(lookupGetFun === readCallback)// 输出 true

var lookupSetFun = obj.__lookupSetter__('name');// 返回上面我们设置的 Setter函数
console.log(lookupSetFun === reassignCallback)// 输出 true

obj.__proto__.constructor === Object // 因为 obj 的原型式 Object ,因此输出 true

var hasNameProp = obj.hasOwnProperty('name') // 输出 true

obj.isPrototypeOf(Object);

var secondObj = {};
secondObj.__proto__.isPrototypeOf(obj) 
// 因为 secondObj 和 obj 是共用一个原型,因此输出 true

var isNameEnumerable = obj.propertyIsEnumerable('name');
// 属性存在 且 可枚举时,才返回 true

defineProperty

上面一些函数的返回值其实与属性的三个特性有关:可写,可配置,可枚举。

可写,只有设为 true 时,该属性才能被赋值运算符赋值, 默认 true

可配置,只有设为true 时,描述符才能够被改变,也能够被删除。默认 true

可枚举,只有设为true 时,属性才能够出现在对象的枚举属性中。默认 true

好了先看下语法:

// 参数 : 要设的对象,要设的属性,描述符(是个对象)
Object.defineProperty(obj, prop, descriptor)
描述符就是对上面说的三个特性的配置。看个例子

Object.defineProperty(obj, 'secondName', {
    // value: "hust",
    // writable: true,
    // 数据描述符和存取描述符不能混合使用, value、writable 跟 get、set 不能同时使用。
    configurable: true,
    enumerable: true,
    get: readCallback,
    set: reassignCallback
});
注意,这里 value、writable 和 get、set一定不能同时出现,否则报以下错误。

Uncaught TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute

另外 Object 本身还有一些很实用的函数,有兴趣的可以自己阅读下Mozilla 官方文档。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object






<think>我们正在讨论JavaScript中对象的原型机制。根据引用[1]和引用[2],我们可以知道: -每个JavaScript对象(除了通过`Object.create(null)`创建的对象)都有一个原型(prototype)。-对象的原型可以通过`__proto__`属性(非标准,但被广泛支持)或`Object.getPrototypeOf()`方法访问。 -构造函数(如`Object`)有一个`prototype`属性,它指向一个对象,这个对象将成为由该构造函数创建的实例的原型。 -当我们访问一个对象的属性或方法时,如果对象本身没有这个属性或方法JavaScript会沿着原型链向上查找,直到找到该属性或方法或到达原型链的顶端(`null`)。 因此,答案是:是的,JavaScript对象(除了极少数特殊情况)都有原型原型机制是JavaScript实现继承和属性共享的基础。现在,我将按照要求组织回答:1.使用行内数学表达式(如果有数学内容)用$...$,但这个问题不涉及数学,所以可能不需要。2.独立公式用$$...$$,同样不涉及。 3.使用中文回答。4.生成相关问题。由于问题不涉及数学,我们主要用文字解释。 回答结构:-先明确回答用户的问题:JavaScript对象是否有原型。 -解释原型机制的基本概念。 -举例说明。-引用提供的资料。注意:引用标识要自然添加在引用内容的末尾。另外,生成相关问题。</think>### JavaScript 对象原型机制详解 在 JavaScript 中,**所有对象都有原型**(除了通过 `Object.create(null)` 创建的对象)。原型机制是 JavaScript 实现继承和属性共享的核心,其运作原理如下: #### 1. **原型的基本概念** - 每个对象都有一个隐藏的 `[[Prototype]]` 属性(可通过 `__proto__` 访问),指向原型对象 - 构造函数(如 `Object`)有显式的 `prototype` 属性,该属性将成为其实例的原型 - 原型链查找公式: 当访问对象属性时,JavaScript 引擎按 $$ \text{对象自身属性} \rightarrow \text{原型链属性} $$ 顺序查找 ```javascript // 创建普通对象 const obj = {}; console.log(obj.__proto__ === Object.prototype); // true // 原型链验证 console.log(Object.getPrototypeOf(obj) === Object.prototype); // true ``` #### 2. **原型继承机制** ```mermaid graph LR A[实例对象 obj] --> B[__proto__] B --> C[Object.prototype] C --> D[null] ``` - **属性查找流程**: 1. 检查对象自身属性 2. 未找到则沿原型链向上查找 3. 直到 `Object.prototype`(大多数链的顶端) 4. 若仍未找到返回 `undefined` #### 3. **特殊对象原型** | 对象类型 | 原型链终点 | 创建方式 | |----------------------|------------------|-----------------------| | 普通对象 | `Object.prototype` | `{}` 或 `new Object()` | | 无原型对象 | `null` | `Object.create(null)` | | 内置对象(如 Array) | 内置原型对象 | `new Array()` | #### 4. **原型方法验证** ```javascript const date = new Date(); // 方法继承自原型链 console.log(date.toString()); // 来自 Date.prototype console.log(date.toLocaleString()); // 来自 Date.prototype console.log(date.__proto__ === Date.prototype); // true console.log(Date.prototype.__proto__ === Object.prototype); // true ``` > 关键结论:JavaScript 通过原型链实现**基于原型的继承**(prototype-based inheritance),这与传统面向对象语言的类继承有本质区别[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值