JavaScript学习笔记10

一、原型

  1. 定义:原型是 function 对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
  2. 利用原型特点和概念,可以提取共有属性
  3. 对象属性的增删和原型上属性增删改查。
  4. 对象如何查看原型 ==> 隐式属性__proto__
  5. 对象如何查看对象的构造函数 ==> constructor。
例 
person.prototype //原型(描述一种继承关系),出生时就被定义好了
person.prototype ={} //是祖先

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

上面的 person 和 person1 都有一个共有的祖先 Person.prototype

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

自己身上有属性,原型上也有属性,取近的,用自己的

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

上面通过对象(后代)改原型(祖先)是不行的,在对象里面修改,只作用给自己
改原型都不行,增加肯定也不行。对象可以删除属性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

// construnctor 是构造的意思(隐式是浅粉色)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

浅粉色是系统帮你设置的,深紫色是自己设置的

在这里插入图片描述

在这里插入图片描述

在原型内部自带 constructor,指的是 Car。通过 constructor 能找的谁构造的自己

在这里插入图片描述
在这里插入图片描述

constructor 可以被人工手动更改

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

浅粉色的__proto__是系统的隐式的属性,前面两个_后面两个_,可以修改,尽量不改,在开发的时候,如果很私人的可以写成_private,告诉同事别动。

上面的__proto__放的是原型,__proto__存的是对象的原型

上面的var this ={__proto__:person.prototype };这个对象并不是空的,这个proto,当你访问这个对象的属性时,如果对象没有这个属性,那么就会访问proto索引,看看有没有一个连接的关系,原型和自己连在一起

 Person.prototype.name = 'abc';

        function Person() {
            //var this={
            //  __proto__=:Person.prototype
            //}
        }
        var obj = {
            name: "sunny"
        }
        var person = new Person();
        person.__proto__ = obj;

在这里插入图片描述
在这里插入图片描述

Person 的原型是可以被修改的

Person.prototype.name = 'sunny';

        function Person() {
            //var this={
            //  __proto__=:Person.prototype
            //}
        }

        var person = new Person();
        Person.prototype.name = 'cherry';

在这里插入图片描述

Person.prototype.name = 'sunny';

        function Person() {
            //var this={
            //  __proto__=:Person.prototype
            //}
        }
        Person.prototype.name = 'cherry';
        var person = new Person();

在这里插入图片描述

 Person.prototype.name = 'sunny';

        function Person() {
            //var this={
            //  __proto__=:Person.prototype
            //}
        }

        var person = new Person();
        Person.prototype = {
            name: 'cherry'
        }

在这里插入图片描述
Person.prototype.name这种.的写法是在原有的基础上把值改了。改的是属性,也就是房间里面的东西。

而Person.prototype = {name: ‘cherry’ }是把原型改了,换了新的对象。改了个房间。

上面在new的时候var this={__proto__:Person.prototype}里面的指向Person,此时Person.prototype与__proto__指向的是同一个空间,把他返回给var person

先new再Person.prototype={ name : ‘cherry’ } 已经晚了

在Person.prototype= { name : ‘cherry’ } 时,Person.prototype空间改了,但是__proto__指向的空间不变

上面的步骤实际上是

 Person.prototype.name = {
            name: "a"
        };
        __proto__ = Person.prototype;
        Person.prototype = {
            name: "b"
        };
 var obj = {
            name: "a"
        };
        var obj1 = obj;
        obj = {
            name: "b"
        }

在这里插入图片描述

在这里插入图片描述

上面这种思考过程:程序执行顺序

  1. 先把function Person(){}在预编译的过程中提到最上面
  2. 再执行Person.prototype.name=‘sunny’ 这一样行
  3. 再执行Person.prototype={name:‘cherry’}
  4. 最后执行var person=new Person();执行到new的时候,才会发生var this={__proto__:Person.prototype}
  5. 下面的把上面的覆盖了
  6. 答案是cherry
function Person() {}

在这里插入图片描述

这说明原型里面有原型

 Grand.prototype.lastName = "Deng";

        function Grand() {

        }
        var grand = new Grand();
        Father.prototype = grand;

        function Father() {
            this.name = "xuming";
        }
        var father = new Father();
        Son.prototype = father;

        function Son() {
            this.hobbit = "smoke";
        }
        var son = new Son();

在这里插入图片描述

执行son.toString
//返回function toString(){[native code]},这里返回的是原型链终端的toString

Grand.prototype.__proto__=Object.prototype
//Object.prototype是原型链的终端

二、原型链

  1. 如何构成原型链?(见上一个例子)
  2. 原型链上属性的增删改查
    原型链上的增删改查和原型基本上是一致的。只有本人有的权限,子孙是没有的
  3. 谁调用的方法内部this就是谁–原型案例
  4. 绝大多数对象的最终都会继承自Object.prototype
  5. Objcet.create(原型)
  6. 原型方法上的重写

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

son.fortune.card2='master'这种改,这是引用值自己的修改。属于fortune.name给自己修改,这是一种调用方法的修改


Grand.prototype.lastName = "Deng";

        function Grand() {

        }
        var grand = new Grand();

        function Father() {
            this.name = "xuming";
            this.fortune = {
                card1: "visa"
            };
            this.num = 100;
        }
        var father = new Father();

        Son.prototype = father;

        function Son() {
            this.hobbit = "smoke";
        }
        var son = new Son();

在这里插入图片描述

son.num++是son.num=son.num+1
是先把父级的取过来再赋值+1
所以父亲的没变


    <script>
        Person.prototype = {
            name: "a",
            sayName: function() {
                console.log(name);
            }
        }

        function Person() {

        }
        var person = new Person();
    </script>

console.log(name);写成name就会错,没有这个变量
console.log(this.name);写成this.name就会打印出a

在这里插入图片描述


 Person.prototype = {
            name: "a",
            sayName: function() {
                console.log(this.name);
            }
        }

        function Person() {
            this.name = "b";
        }
        var person = new Person();

在这里插入图片描述

a.sayName()方法调用,就是sayName里面的this指向,是谁调用的这个方法,this就指向谁


Person.prototype = {
            height: 100
        }

        function Person() {
            this.eat = function() {
                this.height++;
            }
        }
        var person = new Person();

在这里插入图片描述

this.height++;
这后面默认有一个return undefined


Person.prototype = {
            height: 100
        }

        function Person() {
            this.eat = function() {
                this.height++;
                return 123;
            }
        }
        var person = new Person();

在这里插入图片描述


例:var obj={};也是有原型的

var obj={};与var obj1=new Object();效果是一样的

写var ovj={};系统会在内部来一个new Object();

obj1.__proto__-------> Object.prototype;
但是在构造对象时,能用对象自变量var obj ={};就不要用var obj1=new Object();


Person.prototype = {}-- > Object.prototype
        function Person() {
        }

对象自变量的原型就是Object.prototype;

三、Object.create(原型)

//var obj = Object.create(原型);

Object.create 也能创建对象。var obj = Object.create(这里必须要有原型)

// var obj = Object.create(原型);
        var obj = {
            name: "sunny",
            age: 123
        };
        var obj1 = Object.create(obj);

在这里插入图片描述


// var obj = Object.create(原型);
Person.prototype.name = "sunny";
function Person() {
}
var person = Object.create(Person.prototype);

在这里插入图片描述


四、绝大多数对象的最终都会继承自Object.prototype

html里面没有添加任何东西
这样就会报错

在这里插入图片描述


html里面没有添加任何东西
只在控制台加上null

在这里插入图片描述


// var obj = Object.create(原型);
var obj = Object.create(null);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

原型是隐式的内部属性,你加是没有用的


// var obj = Object.create(原型);
var obj = Object.create(123);

在这里插入图片描述

Object.create()在括号里面只能放null或者Object,其余会报错


undefined和null没有原型,也就不可能有toString方法

在这里插入图片描述
在这里插入图片描述


下面 123.toString 首先会识别成浮点型,所以在后面直接加.toString 是不行的

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

数字想用toString方法,要经过包装类包装new Number(num)然后.toString


加深上面的理解

var num=123;
//num.toString();--->new Number(num).toString();
Number.prototype.toString=function(){

}
//Number.prototype.__proto__=Object.prototype

而new Number(num).toString的原型是Number.prototype,而Number.prototype上面有一个.toString方法,Number.prototype也有原型Number.prototype.__proto__,原型是Object.prototype

假如new Number上面的prototype上面有这个toString,那么就不用Object.prototype的 toString。而这个 number 上面有这个 toString。

然后number上面的toString调用的是自己重写的toString

原型上有这个方法,我自己又写了一个和原型上同一名字,但不同功能的方法,叫做重写(同一个名字的函数,不同重写方式)

通过返回值,形参列表不同传参
同样的名实现不同功能的,就是重写

在这里插入图片描述


  //    var obnj=Object.create(原型);
        // Object.prototype.toString=function(){

        // }
        Person.prototype = {

        }

        function Person() {

        }
        var person = new Person();

在这里插入图片描述

和原型链上终端方法名字一样,但实现不同的功能,叫做方法的重写。也就是覆盖


在这里插入图片描述
在这里插入图片描述

下面这个也是重写

在这里插入图片描述

在这里插入图片描述


让object上面的toString重写了
所以num.toString()调用的是number.prototype.toString

在这里插入图片描述

在这里插入图片描述

如果调用的是object.prototype.toString结果会不一样

在这里插入图片描述
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

document.write会隐式的调用toString方法,其实打印的是 toString 的结果

在这里插入图片描述

没有原型就不能toString


在这里插入图片描述
在这里插入图片描述

上面这个例子表示:我要打印的是obj,实际上打印出来的是toString方法,也证明了document.write调用的是toString方法

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值