34, JavaScript Object Oriented (| Properties | & built constructor operator & correlation method & object oriented inheritance)

First, object-oriented

1.1 this points to a problem

image

To see who the ultimate function caller yes.
IIFE also function as a direct operation, this is the window object IIFE
arguments class function is an array of objects, such as incoming of a function parameter is 0, let it run: arguments 0 , the context is a function arguments object. Arguments.length even know the difference between length and function.

Constructor 1.2

When a function call by the new operator, when this function is called "constructor" (constructor)

Constructors four steps

Create a new empty object
this binding to the null object
executes the statement
return the object

All new objects out with the same attribute group, the function can be configured as a class, the new instances of the objects are out of function.

When the return statement inside a constructor, attention:

1. If the basic type is the return value, ignoring the return, or return the object created secret
2. If a reference type is the return value of the original object is not returned, but returns a reference to the type of value

Prototype chain of knowledge:

Constructor prototype property is __proto__ property instance. For an object is, __ proto__ this property called his prototype object, is their prototype chain. The prototype chain has a search function, when obj.haha, obj did not have haha property, then looks obj .__ proto__ haha who have no property, and will continue to look for obj. Proto .__ proto__ property who have no property ... haha ...

Second, the prototype chain

++ Object.prototype is the end of all the objects in the prototype chain ++

Any object has a prototype object ( proto ), Object.prototype final point, but Object.prototype very special, it's the end of __proto__ is null.

JS, the object is an object, function, array, etc. regular object, all references type values ​​are objects, they have __proto__ property.

Even, xiaoming of __proto__ also an object that there __proto__.

var obj = {}
console.log(obj.__proto__ === Object.prototype); //true

Object () constructor is built, all objects can be considered Object new out

var obj = new Object();
obj.name = "小明";
obj.age = 12;
console.log(obj)
console.log(obj.__proto__ === Object.prototype);

image

"{}" __Proto__ object point Object.prototype, since it is the Object new out.

function People(name,age){
   this.name = name;
   this.age = age;
}
var xiaoming = new People("小明",12);
console.log(xiaoming.__proto__ === People.prototype); //true
console.log(xiaoming.__proto__.__proto__ === Object.prototype); //true
console.log(xiaoming.__proto__.__proto__.__proto__);; //null

image

In summary, xiaoming prototype People.prototype also has a prototype, Xiao Ming complete family tree:
image

Object.prototype is not the only object __proto__ of all other objects, functions, arrays, regular and others have __proto__

Third, the built-in constructor

JS built many constructors, they are also referred to as "basic value of", "reference value of" wrapper class.

3.1 constructor type reference value

The value of reference type constructor: Object (), Function (), Array (), RegExp ()

3.1.1 Object () function

Object () constructor is built, it can be directly new, returns a null object, attributes may be added to the empty object:

var obj = new Object();
obj.name = "小明";
obj.age = 12;
console.log(obj)
console.log(obj.__proto__ === Object.prototype);

Equivalent to:

var obj = {
name:"小明",
age:12
}

3.1.2 Function () function

All function literal is an instance of it

function sum(a,b){
   alert(a+b);
}
sum(3,5);

Equivalent to:

var sum = new Function("a","b","alert(a+b);alert('算完啦!')");
sum(4,5)

In the new Function when the first list all the parameter list, the last parameter is a function of the body, it is noted parameters are strings.

console.log(sum.__proto__ === Function.prototype)

image

Any ++ functions are Function () constructor example, Object is an instance of Function, Function myself own instance. Function own new yourself. ++

console.log(Object.__proto__ === Function.prototype);   //true
console.log(Function.__proto__ === Function.prototype); //true

image

The relationship ++ Function and Object: ++

console.log(Function.prototype.__proto__ === Object.prototype);    // true
console.log(Function.__proto__.__proto__ === Object.prototype);    // true
console.log(Function.__proto__.__proto__ === Object.__proto__.__proto__);    // true
console.log(Function.__proto__ === Object.__proto__);    // true

image

3.1.3 Array () function

Array () built-in system array constructor, any arrays are Array () new new out.

var arr = new Array();
arr[0] = 100;
arr[1] = 200;
arr[2] = 300;
console.log(arr);

Equivalent to:

var arr = [100,200,300];

函数能填参数,表示数组长度,但数组还是空数组:

var arr = new Array(8);

常用的数组方法,都定义在Array.prototype身上。
image

var arr = [3,3,4,4];
console.log(arr.__proto__ === Array.prototype); //true
console.log(arr.__proto__.__proto__ === Object.prototype); //true

3.1.4 RegExp()函数

任何正则表达式RegExp()函数的实例。

var reg = /\d/g;
//等价于
var reg = new RegExp("d","g");
console.log(reg.__proto__ === RegExp.prototype); //true
console.log(reg.__proto__.__proto__ === Object.prototype); //true

3.2基本类型值“包装类”

【Number()、String()、Boolean()】

基本类型值的构造函数,被称为“包装类”。JS体系为了完整,所以就人为造出了这三个包装类,没有什么用。

3.2.1 Number()函数

用于创建数字对象:

var a = new Number(3);
console.log(a)
console.log(typeof a)

image
用内置构造函数创建数字的时候,得到一个对象,这对象的原始值属性是:
[[PrimitiveValue]]: 3  //这个属性不可被枚举。

它和字面量创建数字的区别:

var a = new Number(3);
var b = 3;
console.log(a == b);   //true
console.log(a === b);  //false

用Number()创建的对象,可以参与数学运算:
Number的实例是一个对象,但这个对象一旦参数运算,将变为普通Number类型

var a = new Number(3);
a = a * 3
console.log(a)
console.log(typeof a)

image
Number()也可以用来把各种值转换为数组(不能转就是NaN),不需要用new调用。

console.log(Number("12"));   //12
console.log(Number("12年")); //NaN
console.log(Number(""));     //0
console.log(Number(false));  //0
console.log(Number(true));   //1
console.log(Number({}));     //NaN
console.log(Number([]));     //0
console.log(Number([1,2]));  //NaN

任何需要转为数字的隐式转换,实际上就是在调用Number函数。

3.2.2 String()函数

var str = new String("我喜欢你");
console.log(str)

image
String()也可以用来转换:

console.log(String(123));   //"123"
console.log(String(true));  //"true"
console.log(String([]));    //""
console.log(String([1,2,3])); //"1,2,3"
console.log(String(NaN));  //"NaN"
console.log(String({}));   //"[Object Object]"

image

3.2.3 Boolean()函数

不管值是false还是true,都能通过if的验证,都是true。

var b = new Boolean(false);
console.log(b)
console.log(typeof b);
if(b){
   alert("真的");
}

3.3内置构造函数之间的关系

就三句话,死记:

1、“{}”对象是被Object new出来的。所以它的__proto__就会指向Object.prototype。
2、任何函数都是Function new出来的实例,所以只要它是函数(构造函数也是函数),它的__proto__就会指向Function.prototype。
3、Function是所有构造函数的妈,它自己也是自己的妈。
小明不是Object new出来的,是People new的,它的__proto__指向People.prototype。

image

console.log(Object.__proto__.__proto__ === Object.prototype); //true
console.log(Function.__proto__.__proto__ === Object.prototype); //true
console.log(Object.__proto__ === Function.prototype);  //true
console.log(Function.__proto__ === Function.prototype);  //true
console.log(Array.__proto__ === Function.prototype);  //true
console.log(RegExp.__proto__ === Function.prototype);  //true
console.log(Number.__proto__ === Function.prototype);  //true
console.log(String.__proto__ === Function.prototype);  //true
console.log(Boolean.__proto__ === Function.prototype);  //true

image

四、相关的方法、属性、运算符

4.1 hasOwnProperty()方法

返回布尔值(true/false),用来检测某属性、某方法是不是在自己身上。

function People(name){
   this.name = name;
}
People.prototype.sayHello = function(){
   alert("你好");
}
var xiaoming = new People("小明");
console.log(xiaoming.hasOwnProperty("name"));     //true
console.log(xiaoming.hasOwnProperty("sayHello")); //false
console.log(xiaoming.hasOwnProperty("toString")); //false

4.2 in运算符

返回布尔值(true/false),in运算符可以检查某个对象有没有能力调用某属性、某方法,而不管这个属性或方法是否定义在自己身上,还是原型身上。

字符串 in 对象

function People(name){
   this.name = name;
}
People.prototype.sayHello = function(){
   alert("你好");
}
var xiaoming = new People("小明");
console.log("name" in xiaoming);     //true
console.log("sayHello" in xiaoming); //true
console.log("toString" in xiaoming); //true

4.3 constructor属性

每一个函数的prototype对象都有一个constructor属性,指向构造函数。

function People(name){
   this.name = name;
}
var xiaoming = new People("小明");
console.log(People.prototype)
console.log(People.prototype.constructor === People); //true
console.log(People.prototype.hasOwnProperty("constructor")); //true
console.log(xiaoming.constructor === People);  //true
console.log(xiaoming.hasOwnProperty("constructor"));  //false

image

4.4 instanceof运算符

返回布尔值,用来检查某个对象是不是某个函数的实例

o instanceof F

如果F.prototype在o的原型链上,返回true,否则返回false
image

function People(name){
   this.name = name;
}
var xiaoming = new People("小明");
function Dog(){
}
console.log(xiaoming instanceof People); //true
console.log(xiaoming instanceof Object); //true
console.log(xiaoming instanceof Dog); //false

小题目:

console.log(Object instanceof Object); //true
console.log(Function instanceof Function); //true
console.log(Function instanceof Object); //true
console.log(Number instanceof Function); //true
console.log(Number instanceof Number); //false

我们发现object.prototype是所有对象原型链的终点,所以我敢说任何原型X一定true。

x instanceof Object
// Function的prototype出现在自己的__proto__线上,所以是true
console.log(Function instanceof Function); //true

五、练习题

5.1题目1

function A(){}
    function B(){
        return new A(); //返回了引用类型值
    }
    A.prototype = B(); //返回了一个A的实例1
    B.prototype = new B();//返回了一个A的实例2
    var a = new A(); //返回了一个A的实例,赋给a
    var b = new B(); //返回了一个A的实例,赋给b

    console.log(a.__proto__ == b.__proto__);
    console.log(a instanceof A); //true 
    console.log(a instanceof B); // false
    console.log(b instanceof A); //true
    console.log(b instanceof B); //false

image

5.2题目2

[].constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor.constructor === Function //true

image

六、继承

6.1什么是继承

计算机领域,关注两个类的关系,就是看属性群之间的关系。

比如:人类和狗狗类属性群,难免会有交集,但是不完全重合,此时可以认为两个类没有任何关系。
image
看看人和学生的属性群:
image
| 小学生肯定是人,人的属性学生全有,人能做的事情学生都能做。
l 但是反过来,小学生的属性和能力,人不一定有。

“学生”细化了、精分了、更具体了“人”。
“学生”的实例要比“人”的实例少。
“学生”一定是人,但“人”不一定是学生。

术语上,我们称“学生类”继承(extend)“人类”。人类叫“父类(超类)”,学生类叫“子类”。

A继承了B,此时要意识到:
A拥有B的所有属性和方法
A的属性群比B大
A丰富了B,A把B变得更具体,范围更小。

6.2 JavaScript实现继承

JavaScript实现两个类:People类,Student类,要求People类拥有的属性和方法,Student类的实例也要拥有People的属性和方法。Student还能丰富自己类的属性和方法,很简单,只要求巧妙设计原型链。

//人类
function People(name,age,sex){
   this.name = name;
   this.age = age;
   this.sex = sex;
}
People.prototype.sayHello = function(){
   alert("你好,我是" + this.name);
}
People.prototype.sing = function(){
   alert("都拉米发骚啦稀~~~");
}
// 学生类
function Student(name,age,sex,id,banji,socre){
   People.apply(this, arguments)
   // this.name = name;
   // this.age = age;
   // this.sex = sex;
   this.id = id;
   this.banji = banji;
   this.socre = socre;
}
//下面这条语句可以实现继承
Student.prototype = new People();
Student.prototype.study = function(){
   alert(this.name + "在学习!");
}
var xiaoming = new Student("小明",12,"男",100001,"初三一班", 100)
xiaoming.study();
xiaoming.sayHello();
xiaoming.sing();
注:People.apply(this, arguments)和Student.prototype = new People();要在Student.prototype.*** = function(){}之前

jQuery创始人John Resig写了一个小包,20多行代码,解决了JS继承恶心的问题。

https://johnresig.com/blog/simple-javascript-inheritance/

引包之后,这个包改变我们创建JS类的方式(和jQuery一样改变了写JS的方式)

//人类
var People = Class.extend({
   init : function(name,age,sex){
       this.name = name;
       this.age = age;
       this.sex = sex;
   },
   sayHello:function(){
       alert("你好,我是" + this.name);
   },
   sing:function(){
       alert("都拉米发骚啦希~~~");
   }
})

//学生类
var Student = People.extend({
   init : function(name,age,sex,id,banji,socre){
       this._super(name,age,sex); //继承父类的属性
       // this.name = name;
       // this.age = age;
       // this.sex = sex;
       this.id = id;
       this.banji = banji;
       this.socre = socre;
   },
   study :function(){
       alert(this.name + "在学习!");
   }
})
var xiaoming = new Student("小明",12,"男",100001,"初三一班", 100)
console.log(xiaoming)
xiaoming.study();
xiaoming.sing(); 

七、上升到面向对象

面向对象是一种编程思想,两个字就能概括:自治(自己管理自己),深入理解,就是封装。每个对象个体仅需要管理自己即可。
面向对象初学阶段,当你遇见大量的结构、功能、性质、什么都一样的对象的时候,立刻想到用面向对象技术。

现在要给大家一个思维定式,面向对象的时候怎么编程:
  思考初程序中有哪些类,在前期我们的业务仅仅只有一个类,后期类会有多个。
  每个类有哪些方法和属性,就是他们自己有什么功能
  每个类之间如何通信、交互数据、此时就要用到设计模式,比如中介者模式、发布订阅模式(观察者模式)。
  这个类怎么进行单元测试,如果保证自己这个类鲁棒,每个类都鲁棒了,整个程序就鲁棒。
我们之前的编程叫“面向过程”,现在是“面向对象”编程(OO)

7.1面向对象-红绿灯(案例)

Consider a problem, you want to make page one effect: 100 traffic lights, click on a traffic light, red light changed from yellow, click again to change from yellow green, click again on the green light becomes red ...

There is a semaphore, and then click the button, the signal variation 0,1,2,0,1,2,0,1,2 ... then let div of background-position changes, you have to write 100 semaphores, 100 boxes, 100 events.

Things appear on the page is the traffic lights, and they have the same look, nature, function, so you can let the traffic lights designed as a class.

What each class is responsible for: ① state quantity ②DOM elements.

JS Each object has two attributes, one attribute state, the other is a DOM object

Simply put, DOM objects now become a property of JS object.

这个类有哪些属性?
  DOM属性
  颜色属性

哪些方法?
  初始化方法 init()
  换颜色方法 changeToColor()
  绑定事件方法 bindEvent()

The first step: DOM structure and CSS styles, make sure to put a div element could see the lights out.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style type="text/css">
     *{ margin: 0; padding: 0;}
     div.honglvdeng{
         position: relative;
         width: 140px;
         height: 328px;
         background: url(./images/honglvdeng.jpg);
     }
    </style>
</head>
<body>
    <div id="box">
        <div class="honglvdeng"></div>
    </div>
</body>
</html>
//第二步:创建红绿灯类
//new Honglvdeng()时,会执行构造函数中的语句
//所以在构造函数中创建一个DOM对象,然后让它上树
function Honglvdeng(){
   //每一个类中有两个属性:状态量、DOM
   this.dom = null;
   //状态属性
   this.state = 0;
   //初始化方法
   this.init();
   //事件监听方法
   this.bindEvent();
}
//为了程序美观,整洁,好更改和可插拔性高,方便维护,将DOM和上树语句都写在初始化方法中
Honglvdeng.prototype.init = function(){
   //创建DOM
   this.dom = document.createElement('div');
   //给DOM添加类名
   this.dom.className = 'honglvdeng';
   //上树
   document.getElementById("box").appendChild(this.dom);
}

//第三步:添加事件监听
Honglvdeng.prototype.bindEvent = function(){
   //备份this,因为事件监听里面的this表示dom元素本身
   var self = this;
   this.dom.onmouseenter = function(){
       // 改变信号量
       // self.state++;
       // if(self.state > 2) self.state = 0
       //判断简写
       self.state = ++self.state % 3;
       self.dom.style.backgroundPositionX = -155 * self.state +'px';
   }
}
//第四步:实例化100个红绿灯
var count = 100;
while(count--){
   new Honglvdeng();
}

Article reproduced in mufengsm

Guess you like

Origin www.cnblogs.com/zhongchao666/p/10966544.html