JavaScript的原型和原型链 (一)

版权声明:刘家军 https://blog.csdn.net/qq_42911663/article/details/85319110

关于js的原型和原型链,有人觉得这是很头疼的一块知识点,相较于普通语法,它更难以理解一些,在开发上也较不常见。但这并不意为这它不重要,相反,它很重要。要了解原型和原型链,我们得先从对象说起

创建对象

通过对象字面量

通过对象直接量创建对象,这是最简单也是最常用的创建对象的方式

let obj= {};
let LJJ = {name: "刘家军",age: 21};
let YH = {name: "袁姮",age: LJJ.age + 1};

通过new创建对象

通过new运算符创建并初始化一个新对象,关键字new后跟随一个函数调用,这个函数成为构造函数(constructor),构造函数用来初始化一个新对象,js包含了一些内置的构造函数

let  obj = new Object()//创建一个空对象等同于 let obj = {}
let  arr = new Array()//创建一个空数组等同于 let arr = []

上面的Object(),Array(),都是js内置的构造函数
除了内置的构造函数,我们还可以使用自定义构造函数来初始化对象

function fun(){
    console.log("这是一个自定义构造函数")
};
let myFun= new fun();

通过Object.create()

Object.create(proto, [propertiesObject]) 创建一个新对象,包含两个参数
proto, 新创建对象的原型对象
propertiesObject,可选。 包含一个或多个属性描述符的 JavaScript 对象

let obj = Object.create(Object.prototype) //创建一个空对像
const YH = {
  sex: "woman",
  fun() {
    console.log(`我的名字是:${this.name}, 性别: ${this.sex}`);
  }
};

const LJJ = Object.create(YH); // 继承YH的 sex 属性 与 方法
LJJ.name = "刘家军"; // name 是LJJ上的属性 但不是YH上的
LJJ.sex = "man"; // 继承的属性可以被覆盖
LJJ.fun();

对象分类

我们都知道 JavaScript中万物皆对象,但对象之间也是有区别的。分为函数对象和普通对象。
函数对象可以创建普通对象,(这个我们上面讲过了),回顾一下

function fun(){
    console.log("这是一个自定义构造函数")
};
let myFun= new fun();

普通对象没法创建函数对象,凡是通过new Function创建的对象都是函数对象,其他都是普通对象(通常通过Object创建),可以通过typeof来判断。

function fun1() {};
console.log(typeof fun1) // "function"

let obj1 = new fun1();
console.log(typeof obj1) // "object"
let obj2 = {};
console.log(typeof obj2) // "object"

关于函数的创建,注意以下写法等价

function fun1() {}
等价于
let fun1 = new Function();

function fun2(a,b){
  console.log(a+b);
}
fun2(1,2)
等价于
let fun2= new Function('a','b',`console.log(a+b)`);
fun2(1,2)

简单回顾一下
我们将对象分为函数对象普通对象,函数对象的级别要要高于普通对象,可以通过函数对象创建普通对象,但是无法通过普通对象创建函数对象
好了,进入正题!

什么事js原型

每一个js对象(null除外)都和另一个对象相关联,“另一个”对象就是原型,每一个对象都从原型继承属性
所有通过对象直接量创建的对象都具有同一个原型对象,可以通过Object.prototype获取对原型对象的引用,注意以下代码

// dmeo1
const obj =new Object()
alert(obj.prototype) // undefined
alert(Object.prototype) // [object Object]
// demo2
function fun(){
    console.log("这是一个自定义构造函数")
};
alert(fun.prototype) // [object Object]

看以上代码,obj 为普通对象,obj的prototype为undefined,Object为js内置构造函数,Object存在prototype
我们得出以下结论
每一个函数对象都有一个prototype属性,但是普通对象是没有的;
换个方式再说一遍,只有函数对象才会存在prototype属性,普通的对象不存在

还没结束,看如下代码

function fun(){
    console.log("这是一个自定义构造函数")
};
console.log(fun.prototype)

输出:

const obj = {}
console.log(obj.__proto__);

输出:
在这里插入图片描述

const author='刘家军'
console.log(author.__proto__);

输出:
在这里插入图片描述

constructor

是构造函数创建的实例的属性,该属性的作用是指向创建当前对象的构造函数。(这个不是我们今天重点要介绍的)

_ _ proto_ _

这是什么?根据我们的console.log,不难发现,函数对象,普通对象,都存在__proto__,这是什么呢?__proto__和原型链有什么联系呢?__proto__指向谁呢?
预知后事如何 且看明天分解

猜你喜欢

转载自blog.csdn.net/qq_42911663/article/details/85319110