剖析js最底层的方法使用———js的原型

148 阅读7分钟

构造函数

在我们初学js中是否有过疑问,为什么我们能够直接定义一个数字,字符串,数组,对象等类型并使用这就涉及到js最顶层的作用方法,其实我们在学习C,C++,Java语言时,都存在上述情况,这些都要回归到语法设计原理作者所创建的方法,在js中这些基础方法使用就是js的原理。在我们讲解圆形之前让我们来开始介绍构造函数 构造函数和普通函数之间有什么区别呢?其实没有任何区别,构造函数只不过就是new方法构造出来的,其实我们写普通函数也可以通过new来构造(不过行内默认不会以这种方式来写代码)

基础数据类型

  • 1.String(字符串)
  • 2.Number(数字)
  • 3.Boolean(布尔)
  • 4.Object(类)
  • 5.Array(数组)

其实上述的这些类型我们平常使用都有两种方法,让我们以数字Number来举例

let n = new Number(1)
let m = 1
console.log(n);
console.log(m);
//输出
//1
//1

我们在上面提过在我们这一行内公认不去写上面样式的代码,这是因为其实在我们定义变量时,在v8引擎读取下他会把这一段代码转化成new+类型()的函数模式正如上面let m = 1其实在v8引擎中就会读取成m=new Number(),再进行赋值,那v8引擎为什么多次一举,那我们就要聊到这些类型下的方法,那我们以字符串来讲解吧 我们在学习字符串时字符串本身有很多的方法如:tostring、split、trim等,而这些方法到底是怎么来的呢?,其实这些方法就是这些构造函数中,当我们要使用这些方法的时候,就可以方便调用。在使用构造函数的时候我们并不能看到这些方法,其实这些方法就是在存放在原型中,或者说这是这些方法所构成的集合构成了原型。 这是在浏览器下观察到的字符串身上的方法

屏幕截图 2024-11-20 235754.png

原型 prototype 显示原型

概念:原型(prototype)是一个函数被定义出来天生就有的属性 我们结合上面的字符串的原型有没有发现原型和我们所学习的一种结构很相似,对了就i是我们说学习的对象,其实原型也就是一个对象,其实我们可以根据这个结构自己做一份原型并在浏览器使用运行

//Person.prototype ———— 原型 也是一个对象
Person.prototype.say='hello'
function Person(){
    this.name = 'zf'
    this.age = 20
}
let p =new Person()

console.log(p);

让我们来看看在浏览器运行的结果吧

屏幕截图 2024-11-21 001955.png 我们可以看到在我们定义的函数Person()中存在的直接向我们展现内容有age=20,name='zyx' 同时我们看到其内在有个say的属性,其实这个就是他里面的方法即构成模型,所以我们说原型也是一个对象

让我们再看一下原型的应用

function Car(color,owner){
    this.name = "su7";
    this.height = 1400;
    this.long = 5000
    this.color = color
    this.owner = owner
}

let car1 =new Car('red','zyx')
let car2 =new Car('green','zyz')

console.log(car1);
console.log(car2);

我们可以看到其中有很多属性都是一样的都是品牌小米su7自带的属性,那我们就可以把这些相同的属性定义原型中

Car.prototype.name='su7'
Car.prototype.height=1400
Car.prototype.long=5000
function Car(color,owner){
    this.color = color
    this.owner = owner
}

let car1 =new Car('red','zyx')
let car2 =new Car('green','zyz')

console.log(car1);
console.log(car2);

屏幕截图 2024-11-21 004352.png 那就会有人说要是我们想要访问那些被隐藏了的属性该如何操作呢,其实即使三个属性被定义在了构造函数的原型身上,我们还是可以访问的让我们根据实例来看一下

Car.prototype.name='su7'
Car.prototype.height=1400
Car.prototype.long=5000
function Car(color,owner){
    this.color = color
    this.owner = owner
}

let car1 =new Car('red','zyx')
let car2 =new Car('green','zyz')

console.log(car1.name);
console.log(car1.height);
console.log(car1.long);

屏幕截图 2024-11-21 004757.png 这些属性是任然可以访问的

对象原型 “proto_” 隐式原型

上面我们介绍了函数的原型,我们提到过原型就是一个对象,那对象的原型会是什么呢?让我们根据浏览器来看一下对象的原型

屏幕截图 2024-11-21 110038.png 我们发现函数的原型叫做Prototype,刚刚我们查看对象的原型也叫做Prototype,其实这只是在谷歌浏览器的特殊,其实它这是我们要介绍的对象原型 “proto_” 隐式原型

屏幕截图 2024-11-21 111116.png

屏幕截图 2024-11-21 111131.png 我们能看到在函数上的隐式模型和我们上面看到的对象模型是一样的当查找String对象上的一个属性时,如果String的(原型)上没有找到,因为它(String.prototype)也是一个对象,则会往Number.prototype的原型上找,也就是String.prototype.prototype上查找。相当于继承了创建该函数的对象原型(如上图,Number()构造函数其实是由一个对象的构造函数创建的)。所以String构造函数对象的隐式原型(对象原型)会继承Object对象构造函数的显示原型(函数原型)。 所以说对象的隐式会被赋值为创建函数对象的显示模型 我们根据一张图片来进行理解:原型和隐式原型之间的原理即原型链

屏幕截图 2024-11-21 112443.png

new的原理

在js中,new关键字与原型紧密相关,因为当new创建一个构造函数实例,原型链现继承机制,那new到底是怎么执行的呢?

  1. 创建一个新对象
  2. 将构造函数里的this指向这个对象的属性
  3. 创建的对象的 __proto__ = 构造函数的 prototype
  4. return 前面步骤中创建的新对象
Car.prototype.run = "running"
function Car(){
//     // var this = {
//     name:'su7'
//     hight:1400
//     }
// this.__proto__ = Car.prototype

    this.name = "su7"
    this.height = 1400
}
let car = new Car()

运行方式如上面代码示例所示

注意: 并非所有的对象都有隐式模型在函数Object()中有一种特殊的方法creat,而当我们使用该方法赋值null时会出现它没有隐式原型,他不会继续任何东西

屏幕截图 2024-11-21 115818.png