「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」。
最早接触编程时,我学习的C++,后来又用PHP做了几个项目。后来工作就一直是Java开发,早期学习web时,没有太认真学习JavaScript,因为觉得比较简单。这几年深入接触了在以后才发现并不简单。
在ES6中引入了class关键字,不过只是语法糖,还是和Java不同,JavaScript还是基于原型的。并且JavaScript完全是动态的,都是运行时,不存在类,所有的都是实例。即使模拟出来一个类,也只是一个函数写法。
示例:
class People {
constructor(name, sex) {
this.name = name
this.sex = sex
}
eat() {
console.log(`${this.name} 正在吃东西。`)
}
sleep() {
console.log(`${this.name} 正在睡觉。`)
}
}
const lee = new People('小王', '男')
当我们执行const lee = new People('小王', '男')时,实际执行的是:
var lee = new Object();
lee.__proto__ = People.prototype;
People.call(lee);
JavaScript只有一种结构:对象。每个实例对象都有一个私有属性_proto_指向它的构造函数原型对象。这个原型对象也有一个自己的原型对象,层层向上,直到一个对象的原型对象为null。null没有原型,作为原型链的最后一个环节。
几乎所有的JavaScript对象都是位于原型链顶端的Object的示例。
继承方法
JavaScript 并没有其他基于类的语言所定义的“方法”。在 JavaScript 里,任何函数都可以添加到对象上作为对象的属性,函数的继承与其他的属性继承没有差别。
当继承的函数被调用时,this指向的是当前继承的对象,而不是继承的函数所在的原型对象。
示例:
var o = {
a: 2,
m: function(){
return this.a + 1;
}
};
console.log(o.m()); // 3
// 当调用 o.m 时,'this' 指向了 o.
var p = Object.create(o);
// p是一个继承自 o 的对象
p.a = 4; // 创建 p 的自身属性 'a'
console.log(p.m()); // 5
// 调用 p.m 时,'this' 指向了 p
// 又因为 p 继承了 o 的 m 函数
// 所以,此时的 'this.a' 即 p.a,就是 p 的自身属性 'a'
原型对象
绝⼤部分的函数(少数内建函数除外)都有⼀个 prototype 属性,这个属性是原型对象⽤来创建新对象实例,⽽所有被创建的
对象都会共享原型对象,因此这些对象便可以访问原型对象的属性。
例如 hasOwnProperty() ⽅法存在于Obejct原型对象中,它便可以被任何对象当做⾃⼰的⽅法使⽤.
object.hasOwnProperty(propertyName)用法
hasOwnProperty() 函数的返回值为 Boolean 类型。如果对象 object 具有名称为 propertyName 的属性,则返回true,否则返回false。
var person = {
name: "Messi",
age: 29,
};
console.log(person.hasOwnProperty("name")); //true
console.log(person.hasOwnProperty("hasOwnProperty")); //false
console.log(Object.prototype.hasOwnProperty("hasOwnProperty")); //true
上面的示例代码, hasOwnProperty() 并不存在于 person 对象中,但是 person 依然可以拥有此⽅法.
person对象是通过原型链找到了Object对象中的⽅法。
原型链
每个对象都有 __proto__ 属性,此属性指向该对象的构造函数的原型。
对象可以通过 __proto__ 与上游的构造函数的原型对象连接起来,⽽上游的原型对象也有⼀个 __proto__ ,这样就形成了原型链。