原型对象与this

文章详细阐述了JavaScript中的原型对象概念,包括如何通过prototype属性和__proto__属性访问和修改原型对象,以及通过构造函数的prototype属性访问成员。同时,讨论了this的指向问题,展示了如何在不同场景下改变this的指向,如call、apply和bind方法的使用。最后提到了全局作用域和window对象的关系。
摘要由CSDN通过智能技术生成

一、原型对象

1.定义:声明一个函数,那么这个函数默认有一个属性叫prototype,通过这个属性去获取函数的原型对象。

              声明一个对象,它默认有一个属性是__proto__,获取原型对象:obj.__proto__

说明:函数、数组都属于特殊的对象

修改原型对象的属性:Person.prototype.x = 20

给原型对象添加属性:var a={y:200};Person.prototype.x = a

2.访问原型对象中成员的方式:

        1. 直接访问。对象访问成员时,自己没有就访问到原型对象中的成员

        2. 通过对象的__proto__属性访问。先访问到原型对象,然后通过原型对象访问原型对象的成员

        3. 通过对象的构造函数的prototype属性访问。访问到原型对象然后通过原型对象访问原型对象的成员

例子:

function Person() {
    this.age = 1;
      }
Person.prototype.x = 100;
var p1 = new Person();
//方式1:p1对象没有x成员,则在p1的原型对象Person.prototype中找x
console.log(p1.x); //打印100

//方式2:通过p1的原型对象访问x
console.log(p1.__proto__.x); //打印100

//方式3:通过p1的构造函数的原型对象访问x
console.log(Person.prototype.x);//打印100

笔试题:原型对象的操作(设置、获取原型对象内部成员、修改原型对象)(访问后操作,只距离第一种访问方式)

obj.x:若是取x成员,先取自己存储空间中的x,没有就去原型对象中取;

            若是存数据到x成员,自己有就更新数据x;如果没有就添加一个x成员,不修改原型对象的数据。

笔试常考技术点:修改系统的、官方设计的原型对象会被静默(不报错,但代码不生效)。对象不能修改原型对象的成员,但可以修改原型对象的成员的内部数据。

验证:

function Person() { }
Person.prototype = { x: 100, y: { age: 20 } };
p1 = new Person;
p1.x = 11;  //p1中添加x成员,原型对象的x不变
p1.y.age = 666; //没有修改原型对象的成员y的值,而是修改了y内部的数据
console.log(p1); //打印{x:100,y:{age:666}}

二、this与原型对象

this代表它所在的函数运行时, 哪个对象让它运行,谁就是this

1.例题:

function Parent() {
        this.a = 1;
        this.b = [1, 2, this.a];
        this.c = {
          demo: 5,
        };
        this.show = function () {
          console.log(this.a, this.b, this.c.demo);
        };
      }

function Child() {
        this.a = 2;
        this.change = function () {
          this.b.push(this.a);
          this.a = this.b.length;
          this.c.demo = this.a++;
        };
      }

Child.prototype = new Parent();
//Child.prototype={a:1,b:[1,2,1],c:{demo: 5},show:f,__proto__:Parent.prototype{}}

var parent = new Parent();
//parent={a:1,b:[1,2,1],c:{demo: 5},show:f,__proto__:Parent.prototype{}}

var child1 = new Child();
//child1={a:2,change:f,Child.prototype}
var child2 = new Child();
//child2={a:2,change:f,Child.prototype}

child1.a = 11;   
//child1{11,change:f,Child.prototype}
child2.a = 12;   
//child2{12,change:f,Child.prototype}

parent.show();  //1 [1,2,1] 5

child1.show();  //11 [1,2,1] 5
child2.show();  //12 [1,2,1] 5

child1.change(); 
//b=[1,2,1,11] a=11=>4==>5 c=5==>4
//改变了child的原型对象
//a:11==>4==>5    c:5 b:[1,2,1,11]
//Child.prototype = {a:1,b:[1,2,1,11],c{demo:5},show:f,__proto__:Parent.prototype{}}

child2.change(); //b=[1,2,1,12] a=4 c=6 a=5 
//改变了child的原型对象
//a:12==>5==>6   b:[1,2,1,11,12] c:5
//Child.prototype = {a:1,b:[1,2,1,11,12],c{demo:5},show:f,__proto__:Parent.prototype{}}

parent.show();   //1 [1,2,1] 5
child1.show();  //5 [1,2,1,11] 5 
child2.show();  //6 [1,2,1,12] 6 

2.改变this的指向

1. 通过添加并赋值来调用函数

var obj = {
      say: function () { console.log(this); },
      name: "karen",
      };
var obj2 = { name: "jack" };
obj.say();  //打印含有karen的这个函数
obj2.fn = obj.say;   //给obj2添加fn函数属性,以便调用
obj2.fn(); //打印含有jack的这个函数

2. fn.call(obj,29,30,10)

call:将函数的this指向call的第一个参数,并调用该函数;其余参数实际传给了函数 例:getA.call(obj,1,2,3)。

所有函数都有一个call函数,调用时改变函数内部的this。call是一个函数,所以它也有call函数。所有函数都有一个length属性(形参个数)和name属性(函数名)

3.fn.apply(obj,[29,30,10])

将函数的this指向apply的第一个参数,并调用该函数;其余参数需要用数组包裹成一个参数,再传给函数 例:getA.apply(obj,[1,2,3])

4.bind() 只能用在函数的定义式写法中

将函数的this指向bind的第一个参数,不会调用函数,而是返回一个函数的引用地址。要调用该函数时加上小括号,然后在小括号里面传其余参数例:getA.bind(obj)(1,2,3)

      function fn(a, b, c) {
        console.log(a, b, c, this);
      }
//function fn(a,b,c){}.bind 报错,不可以这样写,必须写在定义式里面
      fn(10, 20, 30);  //打印10,20,30,window...没有调用的对象时,默认为window
      var obj = { name: "Allen" };
      
      fn.call(obj, 29, 30, 10);//打印29,30,10 Allen
      fn.apply(obj, [29, 30, 10]);//打印29,30,10 Allen
      fn.bind(obj, 29, 30, 10)();//打印29,30,10 Allen

声明式: function fn(){}.bind({name:'111'})

定义式:say:function(){}

三、全局标识

全局指script脚本的作用域。在全局作用域中声明的变量或者函数,运行的时候会默认添加成为window对象的成员。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值