JavaScript原型与Objective-C概念的类比
将JavaScript的原型和原型对象概念映射到Objective-C,可以这样类比:
1. 原型(Prototype) ≈ Objective-C的类(Class)
在JavaScript中:
- 原型是所有实例共享的"模板"
- 当访问实例的属性/方法时,如果实例本身没有,就会去原型上查找
在Objective-C中:
- 类是所有对象实例共享的模板
- 当调用实例方法时,实际上是在调用类中定义的方法
2. 原型对象(Prototype Object) ≈ Objective-C的类方法列表
在JavaScript中:
- 原型对象是包含共享属性和方法的对象
- 例如:
Array.prototype包含所有数组共享的方法
在Objective-C中:
- 类方法列表(
objc_method_list)包含实例方法 - 例如:
NSArray类的方法列表包含count,objectAtIndex:等方法
3. 原型链(Prototype Chain) ≈ Objective-C的继承体系
在JavaScript中:
- 通过
__proto__或Object.getPrototypeOf()形成的链条 - 例如:
对象 → 构造函数.prototype → Object.prototype → null
在Objective-C中:
- 通过
superclass指针形成的继承链 - 例如:
子类实例 → 子类 → 父类 → NSObject → nil
4. 具体代码对比
JavaScript示例
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log("Hello, I'm " + this.name);
};
var john = new Person("John");
john.sayHello(); // 查找原型上的方法
Objective-C等价示例
// Person.h
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
- (instancetype)initWithName:(NSString *)name;
- (void)sayHello;
@end
// Person.m
@implementation Person
- (void)sayHello {
NSLog(@"Hello, I'm %@", self.name);
}
@end
// 使用
Person *john = [[Person alloc] initWithName:@"John"];
[john sayHello]; // 调用类方法列表中的方法
5. 重要区别
-
动态性:
- JavaScript原型可以在运行时修改
- Objective-C类方法列表在编译后相对固定(虽然也可以通过runtime API修改)
-
继承机制:
- JavaScript是原型继承(委托机制)
- Objective-C是类继承(通过
superclass指针)
-
方法调用:
- JavaScript方法查找是通过原型链向上查找
- Objective-C方法调用是通过消息发送机制(
objc_msgSend)
这种类比可以帮助理解两种语言的设计思想差异,虽然概念不完全相同,但在对象行为共享方面有相似之处。