编程小白的福音:轻松学会JavaScript原型链
前言
JavaScript作为一门堪称“小白诱捕器”的一门语言,其弱类型的特点属实吸引了不少的小白和爱好者尝试。但当掌握了基础语法试图更上一层楼时,JS中一些真正有趣的特点就会张牙舞爪地蹦出来,其独特的原型链机制是它的核心之一。对于新手来说,理解原型链可能会有些困难,但一旦掌握,它将成为你编写高效且可维护代码的利器。本文将介绍JavaScript原型链的基础概念,帮助你更好地理解和利用这一特性。
正文
1. 构造函数与原型
简单来说,要理解原型链其实并不困难,知名北大心理学教授完颜老师的“至理名言”——“这是一个lonely问题”很好地解释了原型链。接下来,用一些代码详细解释为何这是一个“lonely问题”
function Person() {
this.uname = 'reader'
this.age = 18
this.say = function () {
return 'hello'
}
}
let p = new Person()
console.log(p)

2. 原型链的继承
接下来让我们对各位reader动点手脚,准确来说是对Person动点手脚
Person.prototype.hair = 'invisible'
function Person() {
this.uname = 'reader'
this.age = 18
this.say = function () {
return '我要成为JS糕手'
}
}
let p = new Person()
console.log(p);
console.log(p.hair)
console.log(p.say());
这里的prototype翻译过来就是“原型”的意思,这时我们会发现原本各位reader中没有的属性多了出来,这是为何?不仅如此,我们甚至无法通过直接展示获取到新得到的属性
在这个例子中,Person是一个构造函数,通过new关键字实例化了一个reader对象。构造函数的原型(Person.prototype)上定义了speak方法,这样通过p对象就可以访问到这个方法。
但当我们直接通过log或其他的方法直接输出reader对象是看不到这些东西的,这就是隐式继承,也是和显示继承的区别之一。
3. 原型链的继承传承
原型链不仅仅是简单的属性和方法查找,它还提供了一种简单而强大的继承机制。通过正确地设置原型链,我们可以实现对象之间的共享属性和方法,提高代码的复用性。
Ground.prototype.lastname= '贺'
function Ground(){
}
var ground = new Ground()
Father.prototype = ground
function Father() {
this.name = 'A'
}
var father = new Father()
Son.prototype = father
function Son() {
this.hobby = 'reading'
}
var son = new Son()
console.log(son.name);
console.log(son.lastname);
上面的代码或许会令人眼花缭乱,但是实际上也就是原型链的最好解释。祖宗(Ground)的那一辈(prototype)上有个名为lastname 的属性,值为“贺”,这个值通过原型链给到一个确定的祖宗(ground),再给到父亲这一辈(Father),再给到父亲辈中某个确定的人(father),这个lastname的值一直都在,通过一代又一代人的血脉传承,直到传到son身上。当别人问起“您贵姓”时,这个答案并非你自己决定的,而是自你的血脉诞生的那一刻起就确定好了,这也正是为什么开头说到“这是一个lonely问题”。
4. 特殊情况
当然,凡事总有意外,就算是血脉相承也总会有那么几个违背祖宗的家伙
function Bus() {
this.a = 1546
}
Car.prototype = {
constructor: Bus
//创建者修改成功,constructor: 记录对象是由谁创建的
}
function Car() {
this.b = 46
}
var car = new Car()
console.log(car.constructor);
let obj = {
a:1
}
let obj2= Object.create(null)//继承obj创造一个对象
//网易:所有对象都会继承自 Object.prototype?(null)
上面两种情况一种是直接重新声明自己的构造函数,属于是“认贼作父”了,而另一种情况则更像是自己没孩子,所以根据自己的需求领养了一个,虽然没有血缘关系,但还是随了姓,其祖上传下来的属性,领养的孩子身上也会有。
这里还有个比较坑的地方,属于是布兰登老大哥在编写js这门语言的时候遗留下来的老bug了,因为根据原型链的查找方式,访问一个示例的对象的属性会沿着原型链往上找人家的祖宗18代的,直到找到
Object.prototype这个最早的祖先,但null不是,null和对象等引用类型的二进制编码的值都是以000开头,所以不管是typeof还是其他方法,null都会被识别为对象类型,因此在继承null创造对象是不会一路往上找到混元始祖Object.prototype的。
结语
JavaScript原型链是这门语言中一个重要而独特的特性,虽然在初学阶段可能会觉得有些复杂,但它为我们提供了一种灵活而强大的对象模型。通过深入理解原型链,你将能够更好地利用JavaScript的面向对象编程能力,编写出结构清晰、高效可维护的代码。希望本文能够帮助你更好地掌握JavaScript原型链的精髓。
转载自:https://juejin.cn/post/7315846848459604005