首页 > 其他分享 >原型的认识

原型的认识

时间:2022-08-20 17:34:33浏览次数:62  
标签:__ console log proto 认识 Person 原型 prototype

概述:

所有的函数都拥有一个属性 这个属性称为prototype 他是一个对象空间(里面就可以存放对应的数据)他被称为显式原型(prototype)

示例

function Person(){
}
console.log(Person.prototype) //作为一个属性存在 属性是唯一 也就是当前他只有一个
prototype 属性的声明只会声明一次
  • 作为一个属性存在 属性是唯一 也就是当前他只有一个prototype 属性的声明只会声明一次
  • 因为当前这个属性 他对应的是一个对象空间,所以他里面的内容可以被更改和设置的
  • 那么我们就可以在这个里面存放一些内容
function Person(){
}
Person.prototype.username = 'jack' //往这个对象空间存放一个属性 叫username
Person.prototype.age = 18 //往这个对象空间存放一个属性 叫age
Person.prototype.sayHello = ()=>{}
console.log(Person.prototype)

通过实例对象 来访问对应的prototype里面的属性

//取出里面数据 因为构造函数是用于构建对象的 所以我们这个prototype的里面数据 是应该给实例对象去
获取
var person = new Person()
//访问原型中数据(构造函数的prototype里面的属性)实例对象.属性名
console.log(person.username);

prototype是作为构造函数的属性 而构造函数的他只声明一次 那么对应的prototype也只声明一次
也就意味者 你每次拿到的prototype是一个 也就是说他里面存放的数据也只声明一次

var person1 = new Person()
console.log(person1.sayHello == person.sayHello);//true

由此可见 如果想对应的数据只声明一次的情况 我们可以放在原型里面

总结

  • 一般把方法放在原型里面
  • 把属性放在构造函数里面
function Son(){
this.name = 'jack'
this.age = 18
}
Son.prototype.print = function(){
console.log(this); //指向当前的实例对象
console.log(this.name); //指向当前的实例对象
}
new Son().print()

__proto__

概述:每个对象都有一个属性 叫做 __proto__ ,他也是一个内存空间,他指向对应的构造函数的prototype。称为隐式原型。

示例

var obj = {}
console.log(obj.__proto__)

这个对象空间里面也可以存储对应的数据 这个 __proto__ ,他是每个对象都有的,那么实例对象也是个对象他同样也有。

function Person(){
}
let person = new Person()
person.__proto__.username = 'jack'
console.log(person.__proto__)
//通过打印的结果 我们可以看到对应的里面的结果类似于我们的构造的prototype
console.log(Person.prototype == person.__proto__) //ture

从上述代码 大家可以看到对应的构造函数的prototype和对应的实例对象的 __proto__ 是相等,那么
也就证明了对应俩个内容其实是一个对象。那么我们就要明白 谁指向谁,从对应的先后顺序来看,我们
知道先有的构造函数再有的实例对象,所以对应的实例对象的 __proto__ 是指向对应的构造函数的
prototype。那么这个内容是不是就是对象访问原型的属性(所以他又被称为隐式原型),所以我们在
实际使用中并不会用到 __proto__ ,而是通过这个属性来访问对应的显式原型。

总结

实例对象 __proto__ 是指向对应构造函数的prototype
在实际使用中一般不会用 __proto__ ,是通过他来访问对应的prototype

原型链

概述: 原型链其实就对应的寻找原型( __proto__ )的过程组成的一个链式结构,称为原型链。

通过下图我们知道prototype中也包含constructor这个构造器的内容,而 __proto__ 是指向prototype的,所以原型链就是通过__proto__ 来找到prototype,

进而来访问prototype的内容,当然也可以访问到和prototype同级的constructor构造器里的内容,这样一层一层往上找。下面的示例有具体的过程。

 

 

示例

Object.prototype.hello = 'hello'
class Person{
constructor(){
this.username = 'jack'
}
}
Person.prototype.age = 18
class Son extends Person{
constructor(){
super()
}
}
Son.prototype.say = ()=>{}
let son = new Son()
//son的__proto__指向构造函数的原型 对应的Son这个构造函数的__proto__又指向了对应的父类的原型 //对应的父类的构造的函数原型的__proto__指向了对应的Object的构造函数的原型 //那么对应的Object的构造函原型的__proto__ 指向null 这个寻找的过程就称为原型链

console.log(son.__proto__.__proto__.__proto__.__proto__); //那么接下来 我们又知道了对应的对象去访问原型的中属性 直接通过点的形式 //又明白了作用域链 是一层一层向上找变量作用域 //所以我们又可以通过原型链来找对应的属性 原型中的属性 console.log(son.age); //18 console.log(son.hello); //hello console.log(son.abc); //undefined

 

 

 

这个寻找的过程就称为原型链
那么我想问请问对应的对象的属性赋值算不算原型链
不是 不是 不是!!!!
对象的属性赋值的操作有就覆盖 没有就添加
1.找的到就覆盖这个值
2.找不到就添加这个属性
利用原型来实现对应的底层源码
实现对应的数组的高阶函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //some
        Array.prototype.MySome = function(fn){
            var isTrue = false
            //遍历数组
            for(var i=0;i<this.length;i++){
                if(fn(this[i],i,this)){
                    isTrue = true
                    break
                }
            }
            return isTrue
        }
        var x = [1,2,3].MySome(v=>{
            return v>2
        })
        console.log(x)

         //every
         Array.prototype.MyEvery = function(fn){
            var isTrue = true
            //遍历数组
            for(var i=0;i<this.length;i++){
                if(!fn(this[i],i,this)){
                    isTrue = false
                    break
                }
            }
            return isTrue
        }
        var x = [1,2,3].MyEvery(v=>{
            return v>0
        })
        console.log(x)

        //map遍历
        Array.prototype.MyMap = function(fn){
            var arr = []
            for(var i=0;i<this.length;i++){
                if(fn(this[i],i,this)){
                    arr.push(fn(this[i],i,this))
                }
            }
            return arr
        }
        var x = [1,2,3].MyMap(v=>{
            return v
        })
        console.log(x)
        
        //find
        Array.prototype.myFind = function(fn){
            for(var i=0;i<this.length;i++){
                if(fn(this[i],i,this)){
                    return this[i]
                }
            }
        }
        var x = [4,5,6].myFind(v=>{
            return 4
        })
        console.log(x)

        //findIndex
        Array.prototype.myFind = function(fn){
            for(var i=0;i<this.length;i++){
                if(fn(this[i],i,this)){
                    return i
                }
            }
        }
        var x = [4,5,6].myFind(v=>{
            return 4
        })
        console.log(x)
    </script>
</body>
</html>

继承

概述:
继承属于面向对象的三大特性之一,面向对象的三大特性。封装 (抽取内容封装) 继承(子类继承父类)
多态(重写 重载)
继承为子类继承父类的内容,子类可以拥有父类所有的非私有的属性及方法。

继承的实现
extends 关键词(class的继承)*(es6的)

class Person{
constructor(){
this.username = 'jack'
}
}
class Son extends Person{
constructor(){
super()
}
}
console.log(new Son().username) //jack

原型继承(prototype赋值给需要继承的对象)

function Person(){
this.password = '123'
}
function Son(){
}
Son.prototype = new Person()
console.log(new Son().password )//123

组合继承 (原型+call改this指向)

//组合继承
function Person() {
this.password = '123'
}
function Son() {
Person.call(this) //将person里面的this改成Son里面的this
}
Son.prototype = new Person()
console.log(new Son().password) //123

对象冒充(改this指向 找不到原型上的内容(无法继承原型))

//对象冒充
function Person() {
this.password = '123'
}
function Son() {
Person.call(this) //将person里面的this改成Son里面的this
}
let son = new Son()
console.log(son.password);

多态

概述:一个东西多种形态体现,(水
重写 子类重写父类的方法

function Person(){
this.sayHello = ()=>{
console.log('你好')
}
}
function Son(){
this.sayHello = ()=>{
console.log('hello') //子类重写父类方法
}
}
Son.prototype = new Person()
let son = new Son()
son.sayHello() //hello

重载 同一个类里面有多个同名的方法(覆盖 js没有重载)

es6的模块化

import 导入
export 导出
es6的写法

<script type='module'></script>

一个内容如果需要导入 必须先导出(因为只有导出了,才能导入到另外一个地方)

第一种写法
export导出

//对象
const obj = {
username:
"
jack",
password:'123'
}
//函数
const sayHello = ()=>{
console.log('hello');
}
//值
const message = '这个是一个信息'
//数组
const arr = [1,2,3,4]
//变量的接的数据 需要导出必须用{}
export {
obj,
sayHello,
message,
arr
}

import导入

import {
obj,
sayHello,
message,
arr
} from './a.js' //解构
sayHello()
console.log(`obj`, obj);
console.log(`message`, message);
console.log(`arr`, arr);

第二种写法
export 导出

export const obj = {
username:
"
jack",
password:'123'
}
export const sayHello = ()=>{
console.log('hello');
}
export const arr = [1,2,3,4]
export const message = '这个是一个信息'

import 导入

//* 表示所有的 as取别名(随便取)
import * as hello from './a.js'
hello.sayHello()
console.log(`obj`, hello.obj);
console.log(`message`, hello.message);
console.log(`arr`, hello.arr);

第三种写法
export 导出

export default {
obj,
sayHello,
message,
arr
}

import 导入

import a from './a.js'
a.sayHello()
console.log(`obj`, a.obj);
console.log(`message`, a.message);
console.log(`arr`, a.arr);

总结
export 导出内容

  • export const 对应的变量
  • export default 对应的变量
  • export {}

import 导入内容

  • import 变量名 from 文件地址 (所有的话 * 必须取别名 as)

标签:__,console,log,proto,认识,Person,原型,prototype
From: https://www.cnblogs.com/hM1ng/p/16608126.html

相关文章

  • js的原型
    prototype概述:所有的函数都拥有一个属性这个属性称为prototype他是一个对象空间(里面就可以存放对应的数据)他被称为显式原型     从上述代码大家可以看到对......
  • 18js面向对象回顾及原型讲解
    面向对象回顾核心概念:万物皆对象(顶层对象Object)抽取名词作为属性抽取行为作为方法俩种构建对象的方式构造函数构建es6的形式classclassPerson{constructor(......
  • 练习5:常见Array原型方法实现
    Array.prototype.mapArray.prototype.map2=function(callbackfn,thisArg){if(this==null){thrownewTypeError('Cannotreadproperty"map"ofnullor......
  • 认识键盘
    学习打字先要了解键盘,把键盘的每个按键的功能都了解清楚了,后面打字才会更得心应手。常见的键盘有101、104键等若干种。为了便于记忆,按照功能的不同,我们把这101个键划分成......
  • 认识Vue扩展插件
    众所周知,在Vue开发中,实现一个功能可以有很多种方式可以选择,这依赖于Vue强大的功能(指令、混合、过滤等)Vue插件插件通常用来为Vue添加全局功能。插件的功能范围没......
  • 面向对象回顾及原型讲解
    面向对象回顾      核心概念:万物皆对象(顶层对象Object)抽取行为作为方法抽取名词作为属性    俩种构建对象的方式      构造函数构建......
  • 原型 prototype __proto__
    原型概念:每一个构造函数天生自带一个属性为prototype对象,是一个对象数据类型,里面可以存放对应的数据称为显示原型且唯一一般把方法放在原型里,属性放在构造函数里当......
  • 认识Nginx
    无论你用浏览器还是APP访问多数网站,到达的第一站就是Nginx。后来者居上的Nginx千禧年前后,互联网业务迎来了高速发展,老牌的Web服务器都无法满足高性能、高可靠的市场需求......
  • Spring框架认识
    Spring框架1、入职必备篇:Spring框架Spring属于开源框架,Spring是于2003年流行起来的一个轻量级的Java开发基础框架,它是为了解决企业应用开发的复杂性而提供的解决方案......