JS高级教程知识整理——08原型与原型链

01.原型

1.函数的prototype属性
*每个函数都有一个prototype属性,它默认指向一个object空对象(原型对象)
*原型对象中有一个属性constructor,它指向函数对象
2.给原型对象添加属性(一般是方法)
*作用:函数的所有实例对象自动拥有原型中的属性(方法)

实现代码:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <script>
        console.log(Date.prototype, typeof Date.prototype)//包含的属性给创建的实例来使用
        function Fun () {

        }
        console.log(Fun.prototype) //默认指向一个object空对象(没有我们的属性)
       
        //向原型中添加属性(一般是方法)===>实例对象可以访问
        Fun.prototype.test = function () {  
            console.log('test()')
        }
        console.log(Fun.prototype)

        console.log(Date.prototype.constructor === Date) //true
        console.log(Fun.prototype.constructor === Fun)  //true

        var fun = new Fun()//创建实例
        fun.test()//调用test
    script>
body>
html>

02.显示原型与隐式原型

1.每个函数都有一个prototype,就是显示原型(属性)
2.每个实例对象都有一个__proto__,就是隐式原型(属性)
3.对象的隐式原型的值为其对应构造函数的显示原型的值
总结:
*函数的prototype属性:在定义函数时自动添加的,默认是一个空的object对象 this.prototype = {}
*对象的__proto__属性:创建对象时自动添加的,默认为构造函数的prototype属性值 this.__proto = Fn.prototype
*可以直接操作显示原型不能直接操作隐式原型(es6之前)

实现代码:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <script>
        //定义构造函数
        function Fn() {  //内部语句:this.prototype = {} 

        }
        // 1.每个函数都有一个prototype,就是显示原型(属性),默认指向一个空的Object对象
        console.log(Fn.prototype)
        // 2.每个实例对象都有一个__proto__,就是隐式原型(属性)
        //创建实例对象
        var fn = new Fn()  //内部语句:this.__proto = Fn.prototype
        console.log(fn.__proto__)
        
        // 3.对象的隐式原型的值为其对应构造函数的显示原型的值
        console.log(fn.__proto__ === Fn.prototype) //true

        //给原型添加方法
        Fn.prototype.test = function() {
            console.log('test()')
        }
        //通过实例调用原型的方法
        fn.test()
    script> 
body>
html>

03.原型链

1.原型链
*访问一个对象的属性时
*先在自身属性中查找,找到返回
*如果没有,再沿着__proto__这条链向上查找,找到返回
*如果最终没有找到,返回undefined
*别名:实质上是隐式原型链
*作用:查找对象的属性(方法) (一级一级往上查找)
2.构造函数/原型/实例对象的关系
3.构造函数/原型/实例对象的关系2

原型链的补充:
1.函数的显示原型指向的对象,默认是空的Object实例对象(但Object不满足,Object.prototype.proto = null)
2.Function是它自身的实例,所有函数都是Function的实例(包含Function): Funtion = new Function()
3.Object 的原型对象是原型链尽头

实现代码:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <script>
        // console.log(Object)
        // console.log(Object.prototype)
        console.log(Object.prototype.__proto__) //null
        function Fn() {                         //重要!内部语句:this.prototype = {} 
            this.test1 = function () {
                console.log('test1()')
            }
        }
        console.log(Fn.prototype) //注意这里,默认指向一个Object空对象(也是Object实例对象) 实例对象__proto__的值=构造函数Object的prototype的值
        Fn.prototype.test2 = function () {
            console.log('test2()')
        }
        var fn = new Fn()         //重要!内部语句:this.__proto = Fn.prototype
        fn.test1()
        fn.test2()
        fn.toString() //定义在Object原型对象中的方法
        console.log(fn.toString())
        // fn.test3()
        console.log(fn.test3)  //undefined

        // 原型链的补充
        // 1.函数的显示原型指向的对象,默认是空的Object实例对象(但Object不满足,Object.prototype.__proto__ = null)
        console.log(Fn.prototype instanceof Object) //true Fn.prototype是不是Object实例,后面有instanceof的讲解
        console.log(Object.prototype instanceof Object) //false
        console.log(Function.prototype instanceof Object) //true
        // 2.Function是它自身的实例,所有函数都是Function的实例(包含Function)
        console.log(Function.__proto__ === Function.prototype) //true
        // 3.Object 的原型对象是原型链尽头
        console.log(Object.prototype.__proto__)  //null
    script>
body>
html>

构造函数/原型/实例对象的关系图:
JS高级教程知识整理——08原型与原型链_第1张图片
构造函数/原型/实例对象的关系图2:
JS高级教程知识整理——08原型与原型链_第2张图片

*Funcion Foo(){} 就是var Foo = new Function() 所以函数也是一个实例对象,包含prototype和__proto__两个属性.
*实例对象的隐式原型 = 构造函数的显示原型 然而这里,构造函数的隐式原型和显示原型指向同一个对象,说明它是自己创建自己 Function = new Function() //自己创建的 Function.proto = Function.prototype.
*所有函数的隐式原型都应相等(都是new Function()产生的).
*Object create by function.
*函数对象的显示原型指向对象默认是Object空实例对象(由new Object()创建的实例),但Object不满足.
*Object原型对象是原型链尽头

这里手绘了两张图:
JS高级教程知识整理——08原型与原型链_第3张图片JS高级教程知识整理——08原型与原型链_第4张图片
04.原型链_属性问题

1.读取对象的属性值: 会自动到原型链中查找
2.设置对象的属性值: 不会查找原型链,如果当前对象中没有次属性,直接添加此属性并设置其值
3.方法一般定义在原型中,属性一般通过构造函数定义在对象本身上

实现代码:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <script>
        function Fn() {

        }
        Fn.prototype.a = 'xxx'
        var fn1 = new Fn()
        console.log(fn1.a)  //xxx

        var fn2 = new Fn()
        fn2.a = 'yyy'
        console.log(fn1.a,fn2.a,fn2)  //xxx  yyy

        function Person(name, age) {
            this.name = name
            this.age = age
        }
        Person.prototype.setName = function(name) {
            this.name = name
        }
        var p1 = new Person('yang',24)
        p1.setName('yue')
        console.log(p1) //name:'yue',age:24

        var p2 = new Person('qing',24)
        p2.setName('ming')
        console.log(p2) //name:'ming',age:24

        console.log(p1.__proto__ === p2.__proto__) //true
    script>
body>
html>

05.探索instanceof
案例1:
JS高级教程知识整理——08原型与原型链_第5张图片
A instanceof B就是:A是不是B的实例
B函数的显示原型对象(B.prototype)是A.__proto__这条链上的某一个 就返回true,A是B的实例.如下图所示:
JS高级教程知识整理——08原型与原型链_第6张图片
B.prototype与A.__proto__相交于一点,则A是B的实例.以下图来讲解
JS高级教程知识整理——08原型与原型链_第7张图片
所以f1 (A)是Object(B)的一个实例.

案例2:
JS高级教程知识整理——08原型与原型链_第8张图片
完整图部分:
JS高级教程知识整理——08原型与原型链_第9张图片
(1).Object(A) instanceof Function(B),图解如下:
JS高级教程知识整理——08原型与原型链_第10张图片
(2).Object(A) instanceof Object(B),图解如下:
JS高级教程知识整理——08原型与原型链_第11张图片
(3).Function(A) instanceof Function(B),图解如下:
JS高级教程知识整理——08原型与原型链_第12张图片
(4).Function(A) instanceof Object(B),图解如下:
JS高级教程知识整理——08原型与原型链_第13张图片
(5).Object(A) instanceof Foo(B),图解如下:
JS高级教程知识整理——08原型与原型链_第14张图片

06.面试题(画出原型链图)


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <script>
        // 测试题1 画图
        function A () {

        }
        A.prototype.n = 1
        var b = new A()

        A.prototype = {  //原A.prototype属性是指向一个默认Object实例对象,现在指向一个新的对象{n=2,m=3}
            n: 2,
            m: 3
        }
        var c = new A()
        console.log(b.n, b.m, c.n, c.m)// 1 undefined 2 3

        // 测试题2(参照原型链图)
        var F = function(){}
        Object.prototype.a = function(){
            console.log('a()')
        }
        Function.prototype.b = function(){
            console.log('b()')
        }
        var f = new F()
        f.a()
        f.b()  //不能执行
        F.a()
        F.b()
    script>
body>
html>

图解测试题一:
JS高级教程知识整理——08原型与原型链_第15张图片

你可能感兴趣的:(js)