网站首页 > 技术文章 正文
大家一说到原型链知识的都会有这张图。
1) 原型对象与原型属性
- prototype:原型对象,函数在声明的时候自动创建的一块存储区域,用于存储公共的共享属性和方法
- __ __proto__: 原型属性,每一个实例对象在创建的时候都会有一个原型属性__proto__,指向构造函数的prototype
所以可以看出构造函数的prototype和实例对象的__proto__是true指向同一个地方。
什么是构造函数呢?就是new的函数并且首字母是要大写的函数就是构造函数。
平时定义的函数有以下几种方式
function aa(name,age){console.log(name,age)}
aa(“张三”,19)
var bb = function (name,age){console.log(name,age)}
bb("李四",22)
const arrowFn = (name, age) => {
console.log(`我是${name}, 我今年${age}岁`)
}
arrowFn('王五', 10)
其实这几种的本质都是一样的(只考虑函数的声明),都可以使用new Function来声明,是的没错Function也是一个构造函数。上面的写法等同于下面的写法
const aa = new Function(name,age){console.log(name,age)}
aa(“张三”,19)
const bb = new Function(name,age){console.log(name,age)}
bb("李四",22)
const arrowFn = new Function(name,age){ console.log(`我是${name}, 我今年${age}岁`))}
arrowFn('王五', 10)
所以这里的aa,bb,arrowFn其实就是new Function(){}构造函数的实例,举一个例子
对象
咱们平常开发中,创建一个对象,通常会用以下几种方法。
- 构造函数创建对象,他创建出来的对象都是此Function构造函数的实例,所以这里不讨论它
- 字面量创建对象
- new Object创建对象
- Object.create创建对象,创建出来的是一个空原型的对象,这里不讨论它
//1.字面量创建
var obj1 = {
//属性
"name":"如花",
"age":18,
"sex":"男",
//方法
"skill":function(){
console.log("抠脚");
}
}
console.log(obj1);
//问题:代码冗余,适合创建单个对象
//2.实例实例(单例)
var obj2 = new Object(); //创建一个空对象
//添加属性
obj2.name = "连海龙";
obj2.sex = "男",
//添加方法
obj2.skill = function(){
console.log("玩游戏");
}
console.log(obj1);
//问题:代码冗余,适合创建单个对象
咱们来看看字面量创建对象和new Object创建对象两种方式,
其实字面量创建对象的本质就是new Object创建对象
//3.工厂模式创建(普通函数封装)
function createObj(name,age,height){
//创建对象
var obj = new Object();
//添加属性
obj.name = name;
obj.age = age;
obj.height = height;
//添加方法
obj.skill = function(){
console.log("有钱");
}
//返回创建好的对象
return obj;
}
//实例化对象
var obj1 = createObj("吴亦凡",65,179);
console.log(obj1);
var obj2 = createObj("蔡徐坤",30,182);
console.log(obj2);
var obj3 = createObj("旺财",2,30);
console.log(obj3);
//问题:解决代码冗余的问题,识别不明,无法判断对象的类型
console.log(typeof obj2,typeof obj3); //object object
console.log(obj3 instanceof Object); //true 判断实例对象是否由 后面的这个对象创建
//4.声明构造函数
function Student(name, age, sex) {
//1.隐式的创建了一个空对象,让this指向这个空对象
//this = new Object();
//2.执行构造函数中代码(添加属性和方法)
//添加属性
this.name = name;
this.age = age;
this.sex = sex;
//添加方法
this.study = function () {
console.log("good good study,day day up!!!,好好学习,天天自闭");
}
//4.隐式的返回创建好的对象
//return this
}
var s2 = new Student("曾庆文",18,"女");
console.log(s2); // {name: "曾庆文", age: 18, sex: "女", study: ?}
console.log(s2 instanceof Student); //true
//.实例化对象
var s1 = new Student("李华",10,"男");
var s2 = new Student("曾庆文",18,"女");
//问题:解决了识别不明的问题,浪费内存
console.log(s1.study == s2.study);//false 比较的是地址
// new 操作符的作用
1.隐式的创建了一个空对象,让this指向这个空对象
2.执行构造函数中代码(添加属性和方法)
3.让创建的实例对象的__proto__指向构造函数的prototype
4.隐式的返回创建好的对象
原型对象,函数在声明的时候自动创建的一块存储区域,用于存储公共的共享属性和方法
Function和Object
上面咱们常说
- 函数是Function构造函数的实例
- 对象是Object构造函数的实例
那Function构造函数和Object构造函数他们两个又是谁的实例呢?
- function Object()其实也是个函数,所以他是Function构造函数的实例
- function Function()其实也是个函数,所以他也是Function构造函数的实例,没错,他是他自己本身的实例
咱们可以试验一下就知道了
console.log(Function.prototype === Object.__proto__) // true
console.log(Function.prototype === Function.__proto__) // true
constructor
constructor和prototype是成对的,你指向我,我指向你。举个例子,如果你是我老婆,那我肯定是你的老公。
function fn() {}
console.log(fn.prototype) // {constructor: fn}
console.log(fn.prototype.constructor === fn) // true
原型链
Person.prototype 和 Function.prototype
讨论原型链之前,咱们先来聊聊这两个东西
- Person.prototype,它是构造函数Person的原型对象
- Function.prototype,他是构造函数Function的原型对象
都说了原型对象,原型对象,可以知道其实这两个本质都是对象
那既然是对象,本质肯定都是通过new Object()来创建的。既然是通过new Object()创建的,那就说明Person.prototype 和 Function.prototype都是构造函数Object的实例。也就说明了Person.prototype 和 Function.prototype他们两的__proto__都指向Object.prototype
咱们可以验证一下
function Person(){}
console.log(Person.prototype.__proto__ === Object.prototype) // true
console.log(Function.prototype.__proto__ === Object.prototype) // true
复制代码
什么是原型链?
什么是原型链呢?其实俗话说就是:__proto__的路径就叫原型链
原型链终点
上面咱们看到,三条原型链结尾都是Object.prototype,那是不是说明了Object.prototype就是原型链的终点呢?其实不是的,Object.prototype其实也有__proto__,指向null,那才是原型链的终点
至此,整个原型示意图就画完啦!!!
原型继承
说到原型,就不得不说补充一下原型继承这个知识点了,原型继承就是,实例可以使用构造函数上的prototype中的方法
function Person(name) { // 构造函数
this.name = name
}
Person.prototype.sayName = function() { // 往原型对象添加方法
console.log(this.name)
}
const person = new Person('林三心') // 实例
// 使用构造函数的prototype中的方法
person.sayName() // 林三心
复制代码
instanceof
使用方法
A instanceof B
复制代码
作用:判断B的prototype是否在A的原型链上
例子
function Person(name) { // 构造函数
this.name = name
}
const person = new Person('林三心') // 实例
console.log(Person instanceof Function) // true
console.log(Person instanceof Object) // true
console.log(person instanceof Person) // true
console.log(person instanceof Object) // true
最后:记住一句话, 万物皆有__proto__,只有function才会有prototype
参考文章 链接:https://juejin.cn/post/7007416743215759373
- 上一篇: 「原型链」祖师爷什么是原型链呀?
- 下一篇: 一文读懂js中的原型链以及new操作符
猜你喜欢
- 2024-11-10 这样理解 JS 原型链,通透 js原型链的理解
- 2024-11-10 JavaScript-原型链 javascript 原型,原型链 ? 有什么特点?
- 2024-11-10 javascript原型链 js原型链的用处
- 2024-11-10 js 原型/原型链/构造函数/实例/继承
- 2024-11-10 【JavaScript 高级】深入了解原型链
- 2024-11-10 快速读懂JavaScript中的原型链 js的原型和原型链是什么
- 2024-11-10 你可能不太理解的JavaScript - 原型与原型链
- 2024-11-10 我在jacascript中学习到的那些原型链,你知道吗?
- 2024-11-10 JavaScript中的原型prototype和__proto__的区别及原型链概念
- 2024-11-10 面试问题分享 - 5:解释一下 原型、构造函、实例、原型链 之间的关系
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-