【JavaScript】原型与原型链以及判断数据类型方式

💻 【JavaScript】原型与原型链以及判断数据类型方式 🏠专栏:JavaScript
👀个人主页:繁星学编程🍁
🧑个人简介:一个不断提高自我的平凡人🚀
🔊分享方向:目前主攻前端,其他知识也会阶段性分享🍀
👊格言:☀️没有走不通的路,只有不敢走的人!☀️
👉让我们一起进步,一起成为更好的自己!!!🎁

【JavaScript】原型与原型链以及判断数据类型方式

一. 原型(prototype)

将公共的方法提取出来,都写在原型上(只用书写和创建一次)

在内置构造函数的原型上扩展一个新方法,所有的数组都可以使用这个方法

Array.prototype.getMin = function () {
    min = Math.min(...this); // this指向arr
    return min;
}
const arr = [4, 23, 34, 11, 435];
console.log(arr.getMin()); // 4

原型概念

每一个函数:天生自带一个属性 prototype(对象数据类型
每一个对象:天生自带一个属性 __proto__(指向所属构造函数的原型)

实例化对象

  • const p = new Person();
  • p 是 Person的实例对象
  • p 的构造函数是 Person
  • p 的 __proto__ 指向 Person.prototype

JS中内置的构造函数

  • Object
  • Array
  • Date
  • RegExp
  • Function
// eg:
const obj = new Object()
const arr = new Array()
//  任何一个数组,所属的构造函数是 Array
//  任何一个对象,所属的构造函数是 Object

用数组为例

  • 任何一个数组,所属的构造函数都是Array
  • Array原型上的方法,都是给数组使用

一切皆对象

  • 只要是 [] 所属的构造函数就是Array
  • 只要是 {} 所属的构造函数就是Object
  • 只要是 function () {} 所属的构造函数就是Function

问答?

  1. 原型是什么 ?

    一个对象,我们也称为 prototype 为原型对象。

  2. 原型的作用是什么 ?

    共享方法。

  3. 为什么要使用原型对象

    因为构造函数方法虽然很好用,但是存在浪费内存的问题。每一次调用构造函数中的方法都会重新开辟一块新的内存存储(浪费了空间),而原型对象(prototype)可以对象共享可以节省内存。

二. 原型链

原型链:使用__proto__串联起来的链状结构

对象的访问机制

  • 当访问一个对象成员的时候
    • 首先在该对象自己身上查找,如果有直接使用,停止查找
    • 如果没有,会自动去到__proto__查找,如果有直接使用,停止查找
    • 如果仍然没有,继续去到__proto__在上一级查找
    • 如果没有找到,返回undefined, (找到了原型链的顶级 null)

官方:每个实例对象(object)都有一个私有属性(称之为 proto)指向它的构造函数的原型对象(prototype)。该原型对象也有一个自己的原型对象(proto),层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

function Person() {
    this.name = 'tom'
    this.age = 18
}
const p = new Person()
/*
  七个指向问题:(p ==> Person的实例对象)
  	寻找思路主要还是要先了解:该对象所属的构造函数是什么?
  		1.p.__pro__                     ==> Person.prototype
  		2.Person.prototype.__proto__    ==> Object.prototype
  		3.Person.__proto__              ==> Function.prototype
  		4.Function.__proto__            ==> Function.prototype
  		5.Object.__proto__              ==> Function.prototype
  		6.Function.prototype.__proto__  ==> Object.prototype
  		7.Object.prototype.__proto__    ==> null

   所以以下等式结果全为true
        p.__proto__ === Person.prototype
        Person.prototype.__proto__ === Object.prototype
        Person.__proto__ === Function.prototype
        Function.__proto__ === Function.prototype
        Object.__proto__ === Function.prototype
        Function.prototype.__proto__ === Object.prototype
        Object.prototype.__proto__ === null
        */

原型链指向图

请添加图片描述

三. 判断数据类型

判断数据类型的方式

  1. typeof

    语法:typeof(要测试的数据)
    返回值:测试数据对应的数据类型
    缺点:只能检测 基本数据类型

    console.log(typeof (12)); // number
    console.log(typeof ('null')); // string
    console.log(typeof (null)); // object
    console.log(typeof (undefined)); // undefined
    console.log(typeof (true)); // boolean
    console.log(typeof ([])); // object
    console.log(typeof ({})); // object
    
  2. constructor

    语法:数据结构.constructor
    返回值:该数据结构所属的构造函数
    缺点:无法检测 undefined 和 null

    console.log([].constructor); // ƒ Array() { [native code] }
    console.log({}.constructor); // ƒ Object() { [native code] }
    console.log(function () { }.constructor); // ƒ Function() { [native code] }
    console.log((1).constructor); // ƒ Number() { [native code] }
    console.log(('zs').constructor); // ƒ String() { [native code] }
    console.log((null).constructor); // Uncaught TypeError: Cannot read properties of null (reading 'constructor')
    console.log((undefined).constructor); // Uncaught TypeError: Cannot read properties of undefined (reading 'constructor')
    
  3. instanceof

    语法:数据结构 instanceof 构造函数
    返回值:true/false
    缺点:无法检测 undefined 和 null

    console.log([] instanceof Array); // true
    console.log([] instanceof Object); // true
    console.log([] instanceof String); // false
    console.log(null instanceof Object); // false
    console.log(undefined instanceof Object); // false
    let a = 1;
    console.log(a instanceof Number); // false
    
  4. Object.prototype.toString.call()

    语法:Object.prototype.toString.call(要测试的数据)
    返回值:‘[Object 数据类型]’
    所有数据类型都可以检测

    console.log(Object.prototype.toString.call(1)); // [object Number]
    console.log(Object.prototype.toString.call([])); // [object Array]
    console.log(Object.prototype.toString.call({})); // [object Object]
    console.log(Object.prototype.toString.call(true)); // [object Boolean]
    
    console.log(Object.prototype.toString.call(123)); // [object Number]
    console.log(Object.prototype.toString.apply(123)); // [object Number]
    console.log(Object.prototype.toString.bind(123)()); // [object Number]
    

    :不必一定用call()也可以使用bind()()apply(),只要是立即执行即可。

结束语

希望对您有一点点帮助,如有错误欢迎小伙伴指正。
👍点赞:您的赞赏是我前进的动力!
⭐收藏:您的支持我是创作的源泉!
✍评论:您的建议是我改进的良药!
一起加油!!!💪💪💪

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁星学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值