Object-Oriented Programming (2) - liyaozr

Before talked about what is object-oriented programming , then wrote two simple little example, continue to study today.

A wrapper object

1. What is a wrapper

First look at this code:

var str = 'hello';
alert( typeof str ); //string

str.charAt(0);
str.indexOf('e');

Obviously, the type of str that string, only stands to reason that the object will have properties and methods, why string can use it?

In fact, this is the wrapped object.

Respectively, numbers, strings, Boolean values corresponding to Number, String, Booleanthree primary types of primitive objects can be changed to the value (packaged) objects.

When using these three objects as a constructor (with new new), values ​​of the original type may be converted to an object; when used as an ordinary function (without new new), can be any type of value, into the original type of the value .

2. The automatic conversion of the original type

In the above code, the execution str.charAt(0);time, find the corresponding basic types of packaging object type, then all the wrapper object properties and methods to the basic type, then packaged object disappears. This is called automatic conversion of primitive types.

But the object is temporary, we can not modify it.

var str = 'hello';
alert(str.length);  //5

str.number = 10;
alert( str.number );  //undefined

The above code, str is a string, the object itself is not, the length property can not be called. JavaScript engine automatically convert it to a packaging object, call length property on this object. This temporary object is read-only, can not be modified. So, the string can not add new attributes.

3. The method of packaging custom objects

Packaging object may also add custom methods and properties on the prototype for the values ​​of the original type of the immediate caller.

var str = 'hello';

String.prototype.lastValue = function(){
    return this.charAt(this.length-1);
};

alert( str.lastValue() );  //o

Diarch chain

1 What is the prototype chain

In the following example, we created two constructors, the prototype object which in turn is based on the prototype object LandRover Car of the prototype created. The red line is the illustrated prototype chain.

function Car(Logo) {
    this.logo = logo || "unknown name";
}
//设置Car的prototype属性
Car.prototype = {
    start:function() {
         console.log('%s start',this.logo);
    },
    run:function() {
         console.log('%s run',this.logo);
    },
    stop:function() {
         console.log('%s stop',this.logo);
    }
};

//又创建一个构造函数landRover
function LandRover(serialno) {
    this.serialNumber = serialno;  //序列号
}
//设置LandRover的prototype属性
LandRover.prototype = new Car("landRover"); //使用Car创建一个新对象,并把它赋给LandRover构造函数的原型

//创建LandRover对象
var landRover1 = new LandRover("1000");
var landRover2 = new LandRover("1001");

Paste_Image.png Car.prototype by the Object object is also to create, so it's a prototype point Object.prototype

Attribute operations on the prototype chain 2

Modified, deleted property can only be modified, deleted object's own properties

① visit: If we want to access landRover1's serialNumber property, then you can find it directly themselves; if we want to access toString method landRover1, which itself is not, will follow the prototype chain has been online looking until you find or No.

② modify and delete:

Action 1:

landRover1.Logo = landRover1;

Because landRover1 Logo itself does not, although it can access landRover.protoype the Logo property, but it can not be modified, so then it will add a Logo attribute to them, and assigned landRover1, for landRover.protoype the property and Logo no effect

Action 2:

delete(landRover1.Logo);

We landRover1 the Logo property removed, but when we visited landRover1.Logo, or can be accessed as it is to remove its property, had no effect on the properties of the prototype, even if the operation again to make changes, but also ineffective

3 Everything target

① function in JS are objects, so, Car and LandRover these constructors is actually an object, since it is the object, there is certainly a prototype, and Car and LandRover is created out of a new Function, so LandRover and have a Car That prototype Function.prototype.

② The Function.prototype is created out of a new Object, so Function.prototype prototype point to Object's prototype, which is Object.prototype.

③Object.prototype is on top of all prototypes. Paste_Image.png

Three object-oriented properties and methods

1.hasOwnProperty()

1) Role

Determine whether the property of the incoming object's own properties

Understanding prototype Find principle: object lookup to find the corresponding property in the constructor, if the object does not have this property, then the javascript will try to go look for from the prototype, if the prototype object nor the property, then they will from prototype prototype to find, until Object.prototype did not find the property, then it will return undefined.

2) Examples

因此我们仅想在该对象内查找的话,为了提高性能,我们可以使用hasOwnProperty()来判断该对象内有没有该属性,如果有的话,就执行代码(使用for-in循环查找),如下:

var obj = {
    "name":'moon',
    "age":'28'
};
// 使用for-in循环
for(var i in obj) {
    if(obj.hasOwnProperty(i)) {
        console.log(obj[i]);    //moon 28
    }
}

如上使用for-in循环查找对象里面的属性,但是我们需要明白的是:for-in循环查找对象的属性,它是不保证顺序的,for-in循环和for循环最本质的区别是:for循环是有顺序的,for-in循环遍历对象是无序的,因此我们如果需要对象保证顺序的话,可以把对象转换为数组来,然后再使用for循环遍历即可;

2.constructor

1)作用

查看对象的构造函数

function Aaa(){
}
var a1 = new Aaa();
alert( a1.constructor );  //Aaa
2)constructor属性

prototype对象有一个constructor属性,默认指向prototype对象所在的构造函数。

每个原型都会自动添加constructor属性

function Aaa(){
}
//系统会自动添加上
//Aaa.prototype.constructor = Aaa;   
//每一个函数都会有的,都是自动生成的

由于constructor属性定义在prototype对象上面,意味着可以被所有实例对象继承。

3)避免修改construtor属性
function A() {}
var a = new A();
a instanceof A // true

function B() {}
A.prototype = B.prototype;
a instanceof A // false

上面代码中,a是A的实例。修改了A.prototype以后,constructor属性的指向就变了,导致instanceof运算符失真。

所以,修改原型对象时,一般要同时校正constructor属性的指向。

// 避免这种写法
C.prototype = {
  method1: function (...) { ... },
  // ...
};

// 较好的写法
C.prototype = {
  constructor: C,
  method1: function (...) { ... },
  // ...
};

// 好的写法
C.prototype.method1 = function (...) { ... };

3.instanceof运算符

1)作用

对象与构造函数在原型链上是否有关系

function Aaa(){
}

var a1 = new Aaa();
alert( a1 instanceof Object );  //true
2)判断数据类型

请戳这里

4.toString() :

1)作用

把对象转成字符串

这个方法是原型上的,我们可以修改这个方法,但是不建议这样做

var arr = [1,2,3];

Array.prototype.toString = function(){
    return this.join('+');
};

alert( arr.toString() );  //'1+2+3'
2)判断数据类型

利用toString方法来做类型判断

四 对象的继承

1.什么是继承

  • 在原有对象的基础上,略作修改,得到一个新的对象
  • 不影响原有对象的功能

当新创建的对象添加了新的属性和方法时,肯定不能直接用new+构造函数这种方法来直接创建了,因为在添加属性或者方法的时候,也会影响到原来的对象。那我们应该如何实现呢?

2.拷贝继承

方式:

  • 属性的继承 : 调用父类的构造函数 call
  • Inherited methods: for in: copy inherited (jquery also use the copy inherited extend)
function Person(name) {
    this.name = name;
}
Person.prototype.talk = function(name) {
    console.log('My name is '+this.name);
};
var p1 = new Person('moon');
// console.log(p1.name);
// p1.talk();
function Person1(name,age) {
    Person.call(this,name); //这里需要改变this的指向
    this.age = age;
}
function extend(obj1,obj2){
    for (var attr in obj2) {
        obj1[attr] = obj2[attr]; //这个地方不能用"."
    }
}
extend(Person1.prototype,Person.prototype);
var p2 = new Person1('yao',18);
console.log(p1.name); //moon
console.log(p2.name); //yao
p2.talk(); //My name is yao

3. class inheritance

Manner using a constructor function (class) inheritance.

At the outset, JS is no concept of class, a new class is here that the constructor JS seen in class.

Let's look at the so-called step inheritance law

function Person1() {
    this.name = [1,2,3];
}
Person1.prototype.talk = function(name) {
    alert(this.name);
};

function Person2() {}
Person2.prototype = new Person1();

var p1 = new Person2();
p1.talk();
alert( p1.constructor ); //Person1

p1.name.push(4);
var p2 = new Person2();
console.log(p1.name);  //[1,2,3,4]
console.log(p2.name);  //[1,2,3,4]

defect:

1. Modify the point constructor

There are interactions between objects 2. Create out

The right approach: inherit properties and methods separately.

function Person1() {
    this.name = [1,2,3];
}
Person1.prototype.talk = function(name) {
    alert(this.name);
};

function Person2() {
    Person1.call(this); //属性继承仍采取之前的call调用父类的构造函数的方法
}
function Foo() {}  //避免继承属性,只继承方法
Foo.prototype = Person1.prototype;
Person2.prototype = new Foo();
Person2.prototype.constructor = Person2; //修正指向问题

var p1 = new Person2();

p1.talk();
alert( p1.constructor );
p1.name.push(4);
var p2 = new Person2();
console.log(p1.name);  //[1,2,3,4]
console.log(p2.name);  //[1,2,3]

4. prototypal inheritance

Using the prototype to the prototype inheritance, generally used following situation:

function cloneObj(obj){

    var F = function(){};
    F.prototype = obj;
    return new F();

}
var a = {
    name : '小明'
};

var b = cloneObj(a);
alert( b.name ); // 小明

b.name = '小强';
alert( b.name ); //小强
alert( a.name ); //小明

We look at the diagram, assuming new F () = f1

Untitled .png

 第一次执行alert( b.name );时,因为b没有这个属性,所以它会顺着原型链往上找,知道找到a下面的name:小明
 
 执行b.name = '小强';因为b本身是没有name这个属性的,它虽然可以访问a下面的name属性,但是无法修改,所以这时它会在自己身上加一个name属性,并赋值为“小强”,对a中的name属性并无影响

 执行alert( a.name ); 的时候,根据原型链的查找规则,它肯定不会查找到b下面去,更何况a本身就有name属性,所以弹出来的还是“小明”

5. Summary:

  • Copy Inheritance: universal, there are new or not new when can

  • Class inheritance of formula: in the form of a function by a new configuration

  • Prototype Inheritance: no new object


Original: Large columns  of object-oriented programming (2) - liyaozr


Guess you like

Origin www.cnblogs.com/petewell/p/11606544.html