js原型

创建对象

创建对象的方式:
1. 字面量
2. new Object();

  var stu1=new Object();
  stu1.name="小明";
  stu1.eat=function () {
    console.log("吃米饭");
  };

3.自定义构造函数

function Person(name,age) {
  this.name=name;
  this.age=age;
  this.sayHi=function () {
      console.log("我叫"+this.name+"今年"+this.age+"岁了");
  };
}
//创建对象
var p=new Person("小白",20);
var p2=new Person("小黑",20);
//查看p是不是Person这种类型
p.sayHi();
console.log(p instanceof Person);//验证p是不是属于Person类型

5.工厂模式创建对象

 function createObject(name,age,sex) {
    //返回的是一个对象
    return {
      name:name,//前面的name是属性,后面的name是参数--变量
      age:age,
      sex:sex,
      sayHi:function () {
        console.log("您好,我叫:"+this.name);//this就是当前的对象
      },
      play:function () {
        console.log("打游戏很好玩");
      }
    };
  }

  //来个学生对象
  var stu1=createObject("卡卡西",28,"男");
  stu1.sayHi();
  var stu2=createObject("小段",38,"女");
  • 构造函数和工厂函数的区别
    共同点:都可以创建对象
    不同点:
    工厂函数:

    • createObject:有很明显的创建对象的代码:new Object
    • 有return
    • 函数名小写
    • 不能非常的明确对象是属于什么类型.是Object类型

    构造函数:

    • 没有明显的创建对象
    • 没有return
    • 代码少于createObject的代码
    • 把属性和方法直接给this
    • this就是当前对象
    • 函数名大写
    • 非常的明确对象是属于Pearson类型,最终也是Object
原型:
  • 原型的作用:数据共享,实现继承

  • 构造函数中都有一个属性:prototype,叫原型,是程序员用的
    实例对象中都有一个属性:_proto _,叫原型,是浏览器用的,不标准
    无论是prototype还是__proto__都可/以看成是一个对象
    构造函数中的原型(prototype)和实例对象中的原型(proto)都是属性,也都是对象
    构造函数中的prototype和实例对象中的__proto__指向相同
    实例对象的__proto__指向了构造函数的原型对象prototype
    实例对象和原型对象之间的关系通过__proto__来联系,这个关系称为:原型链

  • 原型的写法:

    • 构造函数.prototype.属性=值
    • 构造函数.prototype.方法=function—>函数.prototype,函数也是对象,所以,里面也有__proto__
    • 实例对象.prototype-------->实例对象中没有这个属性,只有__proto__(暂时的)
  • 通过原型可以为js内置对象添加原型的属性或者方法----->系统的内置对象的属性和方法可能不满足现在需求,所以,可以通过原型的方式加入属性或者方法,为了方便开发
    String.prototype.方法=function(){};
    var str=“哈哈”;
    str.方法();---->实例对象可以直接调用原型中的属性或者方法

  • 构造函数中的this和原型对象方法中的this指向相同,都是实例对象

    //动物的构造函数----这里的属性和方法---不需要共享
     function Animal(name,age) {
       this.name=name;
       this.age=age;
       this.play=function () {
           console.log("天天打豆豆");
       };
     }
     //希望性别数据是共享的,希望,吃的行为和跑的行为是共享的,希望玩的行为不是共享的
     //通过原型添加属性和方法---->这些属性和方法会被共享,节省空间
     Animal.prototype.sex="雌";
     Animal.prototype.eat=function () {
         console.log("天天吃大骨头");
     };
     Animal.prototype.run=function () {
         console.log("一跑一蹦跶");
     };
     var dog=new Animal("小段",21);
     var cat=new Animal("小明",23);
    // 性别相同
    console.log(dog.sex);
    console.log(cat.sex);
    //方法调用
    dog.play();
    cat.play();
    //共享的方法调用
    dog.eat();
    cat.eat();
    
     function my$(id) {
     	return document.getElementById(id);
       }
       function ChangeStyle(btnObj,dvObj,json) {
         this.btnObj=btnObj;//按钮
         this.dvObj=dvObj;//div
         this.json=json;
         this.init();//调用原型对象中的方法
       }
       //向原型中添加方法
       ChangeStyle.prototype.init=function () {
         var that=this;//保存对象
         //为元素注册点击事件
         this.btnObj.onclick=function () {
           //设置某个元素中样式多个属性的值
           for(var key in that.json){
             that.dvObj.style[key]=that.json[key];
           }
         };
       };
       var json={
         "backgroundColor":"yellow",
         "width":"500px",
         "height":"200px",
         "border":"2px solid blue"
       };
       var cs=new ChangeStyle(my$("btn"),my$("dv"),json);//实例化对象
    
  • 原型指向可以改变
    实例对象的__proto__指向的是自己的构造函数的prototype,如果构造函数的prototype指向发生改变,那么实例对象的__proto__指向也改变(Person.prototype指向了什么地方,那么实例对象的__proto__也会指向那个地方);如果实例对象的原型指向改变了,再向原型中添加方法,那么这个方法被添加到了所改变指向的位置了

  • 如果实例对象中的属性和原型对象中的属性重名,使用的是实例对象中的属性,原型对象中的该属性的值没有改变;如果实例对象中没有这个属性,但是,原型对象中有这个属性,那么就会使用原型对象中的该属性;使用的方式是需要的搜索,先在实例对象中找这个属性,有,则使用,没有则去原型对象中找,找到了就使用,没找到就是undefined
    为什么这个属性的结果是undefined?因为js是一门动态类型的语言,该对象没有这个属性,点了,那么就有这个属性了,没有赋值,所以结果是undefined

    <body>
      <div id="dv"></div>
      <script>
        var dvObj=document.getElementById("dv");
        console.dir(dvObj);//div
      // dvObj的原型链指向:
        //div--->HTMLDivElement.prototype---->HTMLElement--->Element--->Node--->EventTarget--->Object----null
      </script>
      </body>
    
  • 面向对象的特性:封装,继承,多态

  • 继承:在纯面向对象语言中,继承指的是类(class)与类(class)之间的关系,为了也是数据共享的问题,但是js是一门基于对象的语言,没有类的概念,但是,js可以模拟面向对象,可以把js中的构造函数当成是面向对象语言中的类来看待(可以使用构造函数来代替类)

    // 组合继承
    function Person(name) {
       this.name=name;
    }
    Person.prototype.sayHi=function () {
      console.log("人的打招呼");
    };
    function Student(name,age) {
    	Person.call(this,name);//借用Person的构造函数实现继承,原型对象中的方法不能使用
        this.age=age;
    }
    Student.prototype=new Person();
    //使用组合继承
    var stu=new Student("小白",20);
    console.log(stu.name,stu.age);//属性继承了
    stu.sayHi();
    
    console.dir(stu);//实例化对象stu显示出来
    
    //组合继承:在Student中调用Person的构造函数,实现属性继承,改变Student的prototype的指向,指向的是Person对象的实例(改变prototype的指向)
    //借用构造函数+改变prototype指向--------->组合继承
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值