this更像是一个函数的参数,如果我们以这句话为标准的话,很容易就能模拟出this的行为
因为所有的函数的this都为函数的一个参数,所以其值除了被bind指定了的情况外,以调用方式密切相关,让我们暂时忽略原型链相关内容,用以上标准把代码改写成var father = function (_this, age) {
_this.age = age;
_this.say = function (_this) {
console.log(
"hello i am " + _this.name + " and i am " + _this.age + "years old"
);
};
};
var child = function (_this, age, name) {
_this.name = name;
father(_this, age);
};
const man = {};
child(man, 28, "bill");
man.say(man);
由于this是作为参数传入的那么apply,call方法也就没了用武之地,那么我们来看看bind在这个标准下的表现是怎样的,我们可以轻松的实现bindvar print = (_this) => {
console.log(_this.name + " " + _this.age);
};
/**
*
* @param {*} _bind_func_this bind的函数的this对象,没用用到
* @param {*} func 要绑定this的函数
* @param {*} _this 要和该函数绑定的this
*/
var bind = function (_bind_func_this, func, _this) {
return function (__this, ...args) {
return func(_this, ...args);
};
};
const man1 = { name: "666", age: 666 };
var bindedPrint = bind(null, print, man1);
//绑定死this后,给bindedPrint赋值了一个新的this也是无效的
bindedPrint({ name: "777", age: 777 });
虽然代码很蹩脚,但是确实是在一定程度上模拟出了this的效果,而且还能更好的理解javascript中this的各种表现,假设有以下代码(在非严格模式下执行否则会报错),在javascript中就好像是把this当作了一个参数并根据具当前的调用对象自动传入this,bind了this的除外var obj = {
name: "obj_name",
print() {
console.log(this.name);
}
};
var name = "window_name";
var obj2 = {
name: "obj2_name"
};
var print = obj.print;
obj2.print = obj.print;
//相当于 obj.print(obj)
obj.print();
//相当于 obj2.pring(obj2)
obj2.print();
//等价于window.print也就是print(window)
print();
在javascript中可能很难体会到这一点让我们看看c++ primer里面是怎么说的
在面向对象语言里面说this可能还是不太有说服力,让我们看看用c语言怎么模拟出面向对象的效果,是不是感觉似曾相识,几乎和我们模拟this的javascript代码差不多#include
//C 语言没有类,但可以用结构体充当一个类
//与类不同,结构体只能定义变量,不能够定义函数,可以通过函数指针的方法来实现其功能
//定义“类 ”的成员变量以及方法
typedef struct Person{
char name;
int age;
void (*EatFunction)(struct Person this, int num);
}Person;
//定义函数功能
void EatFunction(struct Person this, int num){
printf("Test\n");
}
//定义“类 ”的构造函数
//与面向对象不同,C语言的“类”的 构造函数不能放在“类”中,只能放在“类”外
//构造函数主要完成 变量的初始化,以及函数指针的赋值
Person *NewPerson(Person *this){
this->name = 'A';
this->age = 18;
this->EatFunction = EatFunction;
}
//主函数调用
int main(){
Person person;
NewPerson(&person);
person.EatFunction(person,0);
return 0;
}
结论:你的问题其实和用c语言怎么实现面向对象这个问题是重合的,this对象更像是一个函数的隐式参数,该值为在调用该函数时由请求该函数调用的对象,