在 JavaScript 中,对象是核心数据类型,而方法则是对象的灵魂——本质上就是挂载在对象上的函数,用于描述对象的行为。本文将从基础定义、this 指向、常用方法、继承与箭头函数等维度,全面梳理 JS 对象方法的知识点,帮你彻底吃透这一核心概念。
一、什么是对象方法?
对象方法,就是赋值给对象属性的函数。当一个函数作为对象的属性值存在时,它就被称为该对象的方法。
- 基础定义方式
(1)普通函数定义(最常用)
javascript
const person = {
name: "掘金用户",
// 对象方法:标准写法
sayHello: function() {
console.log(大家好,我是${this.name});
}
};
// 调用方法
person.sayHello(); // 输出:大家好,我是掘金用户
(2)ES6 简写语法(推荐)
ES6 为对象方法提供了简洁写法,省略 function 关键字,代码更优雅:
javascript
const person = {
name: "掘金用户",
// ES6 方法简写
sayHello() {
console.log(大家好,我是${this.name});
}
};
(3)匿名函数/箭头函数定义
javascript
const person = { // 箭头函数作为方法(注意:this 指向问题) sayHello: () => { console.log(this); // 此处 this 不指向 person! } };
二、对象方法中的 this 指向(重中之重)
对象方法的 this 是运行时绑定的,核心规则:谁调用方法,this 就指向谁。
- 正常调用:this 指向对象本身
javascript
const car = { brand: "特斯拉", getBrand() { console.log(this.brand); } }; car.getBrand(); // 输出:特斯拉 → this 指向 car
- 方法单独调用:this 丢失
如果把对象方法赋值给变量再调用, this 会指向全局对象(浏览器中是 window ,Node.js 中是 global ),严格模式下为 undefined 。
javascript
const car = { brand: "特斯拉", getBrand() { console.log(this?.brand); } }; // 方法赋值给变量,脱离对象调用 const fn = car.getBrand; fn(); // 浏览器:undefined(非严格模式)/ 报错(严格模式)
- 修复 this 指向:call/apply/bind
通过 call() 、 apply() 、 bind() 可以手动指定方法的 this 指向:
javascript
const car = { brand: "特斯拉", getBrand() { console.log(this.brand); } }; const fn = car.getBrand; // call:立即执行,指定 this 为 car fn.call(car); // 特斯拉 // bind:返回新函数,永久绑定 this const boundFn = fn.bind(car); boundFn(); // 特斯拉
- 箭头函数:没有自己的 this
箭头函数不绑定 this,它的 this 继承自外层作用域的 this,因此不适合作为对象方法!
javascript
const person = { name: "掘金", sayHi: () => { // this 继承自全局,而非 person console.log(this.name); // 浏览器:undefined } }; person.sayHi();
三、JavaScript 内置对象方法
JS 原生为所有对象提供了通用方法,挂载在 Object.prototype 上,所有对象都能继承使用:
- Object.prototype.hasOwnProperty()
判断对象自身是否拥有指定属性(不包含原型链上的属性):
javascript
const obj = { name: "掘金" }; console.log(obj.hasOwnProperty("name")); // true console.log(obj.hasOwnProperty("toString")); // false(toString 来自原型)
- Object.prototype.toString()
返回对象的字符串表示,常用于精准判断数据类型:
javascript
const arr = [1,2,3]; console.log(Object.prototype.toString.call(arr)); // [object Array] console.log(Object.prototype.toString.call({})); // [object Object]
- Object.prototype.valueOf()
返回对象的原始值,常用于类型转换:
javascript
const numObj = new Number(10); console.log(numObj.valueOf()); // 10
四、Object 构造函数的静态方法
除了原型方法, Object 构造函数还提供了静态方法(直接通过 Object.xxx 调用),用于操作对象:
- Object.keys() / Object.values() / Object.entries()
快速获取对象的键、值、键值对,返回数组:
javascript
const user = { name: "掘金", age: 25 }; console.log(Object.keys(user)); // ["name", "age"] console.log(Object.values(user)); // ["掘金", 25] console.log(Object.entries(user)); // [["name","掘金"], ["age",25]]
- Object.assign()
合并对象,浅拷贝:
javascript
const target = { a: 1 }; const source = { b: 2 }; Object.assign(target, source); console.log(target); // {a:1, b:2}
- Object.defineProperty() / Object.defineProperties()
定义/修改对象属性的特性(如只读、不可枚举):
javascript
const obj = {}; Object.defineProperty(obj, "name", { value: "掘金", writable: false, // 不可修改 enumerable: true // 可枚举 }); obj.name = "修改"; // 无效 console.log(obj.name); // 掘金
- Object.freeze() / Object.seal()
- freeze() :冻结对象,不可修改、添加、删除属性
- seal() :密封对象,可修改属性,不可添加/删除
javascript
const obj = { name: "掘金" }; Object.freeze(obj); obj.age = 25; // 无效 obj.name = "修改"; // 无效
五、对象方法的高级用法
- 方法中的 getter/setter
ES6 支持通过 get / set 定义访问器方法,实现属性的读取和赋值拦截:
javascript
const person = { _name: "掘金", // getter:获取属性时触发 get name() { console.log("获取name"); return this._name; }, // setter:设置属性时触发 set name(newVal) { console.log("设置name为:", newVal); this._name = newVal; } }; console.log(person.name); // 触发 getter person.name = "掘金用户"; // 触发 setter
- 动态添加/删除方法
JS 对象是动态类型,可以随时增删方法:
javascript
const obj = {}; // 动态添加方法 obj.sayHi = function() { console.log("Hi"); }; // 动态删除方法 delete obj.sayHi;
- 方法的继承
通过原型链,子对象可以继承父对象的方法:
javascript
// 父对象 const animal = { eat() { console.log("吃东西"); } }; // 子对象继承父对象 const dog = Object.create(animal); dog.eat(); // 吃东西(继承自 animal)
六、避坑指南
1. 箭头函数别当对象方法:会导致 this 指向异常,无法获取对象自身属性 2. 注意 this 丢失:方法赋值、定时器、回调函数中,需手动绑定 this 3. 浅拷贝风险: Object.assign() 是浅拷贝,嵌套对象会共享引用 4. 原型方法污染:避免直接修改 Object.prototype ,会污染所有对象
七、总结
JavaScript 对象方法是对象行为的载体,核心要点:
1. 本质是对象属性上的函数,支持 ES6 简写 2. this 指向调用者,箭头函数无自身 this 3. 熟练使用 Object 静态方法和原型方法操作对象 4. 注意 this 丢失、箭头函数、浅拷贝等常见坑