JavaScript面向对象基于原型机制,ES6 class仅为语法糖;构造函数需用new调用,方法挂载prototype以共享;私有成员靠闭包或#字段实现;instanceof依赖原型链,跨iframe会失效。

JavaScript 本身没有传统意义上的类(class)语法(ES6 之前),但完全支持面向对象编程——靠的是原型(prototype)机制和函数对象的灵活性。ES6 引入 class 只是语法糖,底层仍是原型链。
用 function 构造函数模拟类
这是最基础、兼容性最好的方式,也是理解 JS 面向对象本质的关键入口。
构造函数首字母通常大写,调用时必须用 new;内部用 this 绑定实例属性;方法挂载到 Constructor.prototype 上,避免每次实例化重复创建函数。
function Person(name, age) { this.name = name; this.age = age; }Person.prototype.sayHello = function() { console.log('Hi, I\'m ' + this.name); };-
const p1 = new Person('Alice', 25); p1.sayHello();—— 输出Hi, I'm Alice - 漏写
new会导致this指向全局对象(非严格模式下),产生意外污染
class 语法糖背后仍是原型
class 让写法更接近 Java/C#,但别被表象迷惑:它不能定义私有字段(ES2022 #field 是特例)、不支持多重继承、所有方法默认不可枚举,且 class 声明不会被提升(ReferenceError)。
立即学习“Java免费学习笔记(深入)”;
本书全面介绍PHP脚本语言和MySOL数据库这两种目前最流行的开源软件,主要包括PHP和MySQL基本概念、PHP扩展与应用库、日期和时间功能、PHP数据对象扩展、PHP的mysqli扩展、MySQL 5的存储例程、解发器和视图等。本书帮助读者学习PHP编程语言和MySQL数据库服务器的最佳实践,了解如何创建数据库驱动的动态Web应用程序。
class Animal { constructor(name) { this.name = name; } speak() { console.log(this.name + ' makes a sound'); } }class Dog extends Animal { constructor(name, breed) { super(name); this.breed = breed; } bark() { console.log('Woof!'); } }-
Object.getPrototypeOf(Dog.prototype) === Animal.prototype返回true,说明继承关系仍在原型链上 -
class内部方法无法访问arguments,要用剩余参数...args
真正私有成员只能靠闭包或 # 字段
JS 没有 private 关键字(除了 ES2022 的 # 私有字段),常规的 _prefix 命名只是约定,无法阻止外部访问。
- 闭包方式:
function Counter() { let count = 0; this.increment = () => count++; this.getCount = () => count; }——count真正不可访问 -
#字段方式:class Counter { #count = 0; increment() { this.#count++; } getCount() { return this.#count; } }—— 必须用#前缀,且仅限类内访问 -
#字段目前不支持私有方法(#method() {}是合法的,但调用仍受限于作用域规则) - 不要试图用
Symbol模拟私有——它只是唯一,不是私有,Object.getOwnPropertySymbols()仍能枚举出来
原型链 vs 类继承:别混淆“类型检查”逻辑
JS 中判断对象类型,instanceof 查的是原型链,typeof 对对象一律返回 "object",Object.prototype.toString.call() 才可靠。
const d = new Dog('Buddy', 'Golden');-
d instanceof Dog→true,d instanceof Animal→true,d instanceof Object→true -
typeof d→"object",毫无区分度 -
Object.prototype.toString.call(d)→"[object Object]"(不是Dog),因为toString不会读取构造函数名 - 若需自定义类型标识,可加
Symbol.toStringTag:Dog.prototype[Symbol.toStringTag] = 'Dog';,此时Object.prototype.toString.call(d)返回"[object Dog]"
原型链是 JavaScript 面向对象的底层骨架,class 是为了让它看起来更熟悉;真正难的不是怎么写 class,而是什么时候该用闭包封装状态、什么时候该让方法共享在原型上、以及为什么 instanceof 在跨 iframe 场景下会失效——这些细节才决定代码是否健壮。










