js面向对象基础一

JS中的面向对象是在语言的发展中经历了汇编语言,面向过程,面向对象语言。面向过程是亲力亲为,所有代码自己写。而面向对象是对现实世界的模拟,JS准确说是基于对象的语言,不像Java有类的概念。面向对象注重的结果,是抽象出现实世界的世间万物的特征,行为加以描述。

一、了解创建对象的三种方式

  创建对象三种方式:  
   1  字面量的方式,只能描述一个对象。
    2  调用系统的构造函数,是字面量方式的升级。
    3  自定义构造函数方式
    
  <script type="text/javascript">
// 创建对象难点三种方式 一种是


//自定义


function Person(){
name=""
age=""
findPeople:function(){

}
}
//字面量形式
var person={
name:"",
age:"",
area""
findPerson:function(){
console.log("我的世界");

}

//引用构造函数的实例

var person=new Object();
person.name=""
person.findPeople=function(){

}
//自定义构造函数
function  Person(){
this.name=""
this.age=""
this.findPeoson=function(){

}

 }

}

</script>

二、自定义构造函数的时候做了什么事

*new person 的时候做了几件事
    * 1.开辟空间存储对象
    * 2.把this设置为当前的对象
    * 3.设置属性和方法的值

    * 4.把this对象返回

三、工厂函数和自定义函数的区别

function createObject(name,age) {
      var obj=new Object();
      obj.name=name;
      obj.age=age;
      obj.sayHi=function () {
        console.log("您好");
      };
      return obj;
    }
    console.log(Object);
    var obj=new Object();
    console.log(obj);

    console.log(createObject);

共同点:都是函数,都可以创建对象,都可以传入参数
    *
    * 工厂模式:
    * 函数名是小写
    * 有new,
    * 有返回值
    * new之后的对象是当前的对象
    * 直接调用函数就可以创建对象
    *
    * 自定义构造函数:
    * 函数名是大写(首字母)
    * 没有new
    * 没有返回值
    * this是当前的对象
    * 通过new的方式来创建对象

    function Person(name,age) {
      this.name=name;
      this.age=age;
      this.sayHi=function () {
        console.log("您好");
      };
    }
    console.log(Person);

四、构造函数和实例对象的关系

面向对象的思想是先抽象出现实世界的东西。比如说人,抽象出人的构造函数,人的每个个体不一样,就是一种实例化的过程。面向对象先抽象出人的属性和行为,age name sex  行为:eat 然后通过new实例化对象。一句话:实例对象是通过构造函数来创建,构造函数用来创建实例对象的。实例对象的构造器是指向Person的,结果是true,所以,这个实例对象per就是通过Person来创建的。

五、痛点通过构造函数创建对象需要每次在内存中开辟空间,占据原本内存。如何实现数据的共享,不用每次实例化对象才能调用方法和属性。引入原形的概念。原形解决的问题是:数据共享和节省内存空间。

function Person (name,age) {this.name=name;

  }
  Person.prototype.eat=function(){
  console.log("吃大白菜");
  }

六、构造函数和实例对象中的原形

    function Person(name,age) {
      this.name=name;
      this.age=age;
    }
    
    Person.prototype.eat=function () {
      console.log("吃凉菜");
    };

    var p1=new Person("小明",20);
    var p2=new Person("小红",30);

    console.dir(p1);
    console.dir(p2);
    console.dir(Person);
    p1.__proto__.eat();
    console.log(p1.__proto__==Person.prototype
    * 实例对象中有__proto__这个属性,叫原型,也是一个对象,这个属性是给浏览器使用,不是标准的属性----->__proto__----->可以叫原型对象
    * 构造函数中有prototype这个属性,叫原型,也是一个对象,这个属性是给程序员使用,是标准的属性------>prototype--->可以叫原型对象
    *
    * 实例对象的__proto__和构造函数中的prototype相等--->true
    * 又因为实例对象是通过构造函数来创建的,构造函数中有原型对象prototype
    * 实例对象的__proto__指向了构造函数的原型对象prototype

  七、面向对象编程的体会

或许刚开始感觉用DOM操作元素做出事件非常简单代码很少,但是遇到大的项目。还是面向对象简单。编辑一次,可以多次使用,这对不同的的对象可以任意改变,样式。只知道如何使用就可以。比如在最后升级版中,我们封装的事件源可以任意改变,把btn换成p元素。json  中的数据可以按照自己的意愿改变更加方便快捷。

效果是点击按钮改变的是div的颜色。

<input type="button" value=" 现实效果“   id="btn"/>

<div id="div"></div>

<script src="conmmon.js"></script>

<script>

//传统写法

document.getElementById("btn").onclick=function(){

document.getElementById("div").style.backgroundColor="yellow";

}

//使用初级的面向对象的思想编程

function ChangeStyle(btnId,dvId,color){

this.btnId=btnId;

this.dvId=dvId;

this.color=color;

}

ChangeStyle.prototype.init=function(){

var that=this;

this.btnId.onclick=function(){

that.dvId.style.backgroundColor=that.color;

}

}

var cs=new ChangeStyle("btn","dv","yellow");

cs.init();

//面向对象高级

function ChangeStyle(btn,dv,json){

this.btnobj=btn;

this.dvobj=dv;

this.json=json;

}

ChangeStyle.prototype.init=function(){

var that=this;

this.btn.onclick=function(){

for(var key in json){

that.dvobj.style.[key]=that.json[key];

}

}

}

var json={"width":"500px","height":"500px","backgroundColor": "blue", "opacity": "0.2"};

var cs=new ChangeStyle(my$("btn"),my$("dv"),json);

cs.init();// 调用方法

八、构造函数和实例对象、原形对象之间的关系

构造函数可以用来实例化对象,构造函数的属性prototype指向的是构造函数的原形对象。

构造函数的原型对象(prototype)中有一个constructor构造器,这个构造器指向的就是自己所在的原型对象所在的构造函数

构造函数的原型对象(prototype)中的方法是可以被实例对象直接访问的

实例对象中都有_prototype_原形对象指向的是构造函数中protorype原形对象

记住:凡是函数都有:prototype原形对象的属性   凡是对象都有:——proto——原形对象。

由于函数也是对象所以函数中存在:_protype_原形对象。所以函数中存在两个原形对象:prototype/_protype_.

但是,对象不一定是函数,比如:Math对象中就没有prototype


八、原形中的语法

1.原形中字面量语法 会改变constructor的指向。所以需要手动修改student的 constructor 的指向。

这时候在控制台上的:person.prototype中就有了constructor

<script>
    function Student(name, age, sex) {
      this.name = name;
      this.age = age;
      this.sex = sex;
    }
    //简单的原型写法
    Student.prototype = {
      //手动修改构造器的指向
      constructor:Student,
      height: "188",
      weight: "55kg",
      study: function () {
        console.log("学习好开心啊");
      },
      eat: function () {
        console.log("我要吃好吃的");
      }
    };


    var stu=new Student("段飞",20,"男");
    stu.eat();
    stu.study();
    console.dir(Student);

    console.dir(stu);

2.原形对象中的方法是可以相互访问

function Animal(name,age) {
      this.name=name;
      this.age=age;
    }
    //原型中添加方法
    Animal.prototype.eat=function () {
      console.log("动物吃东西");
      this.play();
    };
    Animal.prototype.play=function () {
      console.log("玩球");
      this.sleep();
    };
    Animal.prototype.sleep=function () {
      console.log("睡觉了");

    };

 var dog=new Animal("小苏",20);

    dog.eat();//

九、实例对象的属性和方法的层层搜索机制

实例对象调用方法的时候先在实例中查找,如果没有找到就到。原形中查找。如果原形中还是找到。就会报错。

<script>

    function Person(age,sex) {
      this.age=age;//年龄
      this.sex=sex;
      this.eat=function () {
        console.log("构造函数中的吃");
      };
    }
    Person.prototype.sex="女";
    Person.prototype.eat=function () {
      console.log("原型对象中的吃");
    };


    var per=new Person(20,"男");
    console.log(per.sex);//男
    per.eat();

    console.dir(per);

十、为内置对象添加原形方法

我们所使用的内置对象中的方法大多是通过原形的形式创建,供给我们使用的。所以牛人都是创建对象的,我们一般水平的是使用对象的。

JS中的内置对象,

对象是包含一系列无序属性和方法的集合。他们有很多的方法和属性

Arguments 函数参数集合 
Array 数组
Boolean 布尔对象
Date 日期时间
Error 异常对象
Function 函数构造器
Math 数学对象
Number 数值对象
Object 基础对象
RegExp 正则表达式对象
String 字符串对象

  String.prototype.myReverse=function () {
      for(var i=this.length-1;i>=0;i--){
        console.log(this[i]);
      }
    };
    var str="abcdefg";
    str.myReverse();

十一、把局部变量变成全局变量

了解一个小知识:自调用函数。自调用函数的实现规则

 function fun(){

console.log("我是函数“);

}

fun();调用函数。我们知道这个函数的调用中的fun是函数名。

上面的调用形式等于 (function fun(){console.log("我是函数");})(); //用匿名函数,省略函数名就可以了。记住后面分号一定需要加上。

自调用函数只能够执行一次,就是一次性函数,在声明的同时就直接调用了。

 (function (win) {
      var num=10;//局部变量
     //js是一门动态类型的语言,对象没有属性,点了就有了
      win.num=num;
    })(window);
   console.log(num);
   //如何把局部变量变成全局变量?

   //把局部变量给window就可以了


<script>
    //通过自调用函数产生一个随机数对象,在自调用函数外面,调用该随机数对象方法产生随机数
    (function (window) {
      //产生随机数的构造函数
      function Random() {
      }
      //在原型对象中添加方法
      Random.prototype.getRandom = function (min,max) {
        return Math.floor(Math.random()*(max-min)+min);
      };
      //把Random对象暴露给*对象window--->外部可以直接使用这个对象
      window.Random=Random;
    })(window);
    //实例化随机数对象
    var rm=new Random();
    //调用方法产生随机数
    console.log(rm.getRandom(0,5));
    //全局变量
  </script>

十二、案例 随机小方块

分析:1.首先是小球是随机产生的,所以我们需要一个函数或者说是方法封装随机数的产生。并且需要让其变成全局对象。

2.产生小方块对象,思考它应该具备的属性和方法。宽,高、颜色。然后需要把它添加入map 中,创建元素去装 小方块对象。

3.设置小方块的样式。

4.产生随机位置。

5.实例化对象。每次刷新都会使得小方块的位置变化。

js面向对象基础一

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
  <style>
    .map{
      width: 800px;
      height: 600px;
      background-color: #CCC;
      position: relative;
    }
  </style>
</head>
<body>
<div class="map"></div>
<script src="common.js"></script>
<script>
  //产生随机数对象的
  (function (window) {
    function Random() {
    }
    Random.prototype.getRandom=function (min,max) {
      return Math.floor(Math.random()*(max-min)+min);
    };
    //把局部对象暴露给window*对象,就成了全局的对象
    window.Random=new Random();
  })(window);//自调用构造函数的方式,分号一定要加上




  //产生小方块对象
  (function (window) {
    //console.log(Random.getRandom(0,5));
    //选择器的方式来获取元素对象
    var map=document.querySelector(".map");

    //食物的构造函数
    function Food(width,height,color) {
      this.width=width||20;//默认的小方块的宽
      this.height=height||20;//默认的小方块的高
      //横坐标,纵坐标
      this.x=0;//横坐标随机产生的
      this.y=0;//纵坐标随机产生的
      this.color=color;//小方块的背景颜色
      this.element=document.createElement("div");//小方块的元素
    }
    //初始化小方块的显示的效果及位置---显示地图上
    Food.prototype.init=function (map) {
      //设置小方块的样式
      var div=this.element;
      div.style.position="absolute";//脱离文档流
      div.style.width=this.width+"px";
      div.style.height=this.height+"px";
      div.style.backgroundColor=this.color;
      //把小方块加到map地图中
      map.appendChild(div);
      this.render(map);
    };
    //产生随机位置
    Food.prototype.render=function (map) {
      //随机产生横纵坐标
      var x=Random.getRandom(0,map.offsetWidth/this.width)*this.width;
      var y=Random.getRandom(0,map.offsetHeight/this.height)*this.height;
      this.x=x;
      this.y=y;
      var div=this.element;
      div.style.left=this.x+"px";
      div.style.top=this.y+"px";
    };


    //实例化对象
    var fd=new Food(20,20,"green");
    fd.init(map);

    console.log(fd.x+"===="+fd.y);

  

  })(window);
</script>
</body>
</html>