"js learning notes" object oriented

Posted by not_skeletor on Wed, 05 Jan 2022 14:08:29 +0100

1, Cognitive object

An object is a collection of "key value pairs", which represents the mapping relationship between attributes and values.

var xiaoming = {
    name: 'Xiao Ming',
    age: 12,
    sex: 'male',
    hobbies: ['Football', 'programming']
};
  • Attribute name (key): attribute value (value)

  • In JS, braces represent objects

  • The last attribute is not followed by a comma

1.1 object syntax

k and v are separated by colons, and each group of k:v is separated by commas. Commas can not be written after the last k:v pair.

var obj = {
    k: v,
    K: v,
    K: v,
    K: v
};

1.2 are attributes quoted

If the property key name of an object does not conform to the JS identifier naming convention, the key name must be enclosed in quotation marks.

var xiaoming = {
    name: 'Xiao Ming',
    age: 12,
    sex: 'male',
    hobbys: ['Football', 'Swimming', 'programming'],
    'favorite-book': 'Schunck and betta'
    // There is a short horizontal column in the attribute name, which does not comply with the JS identifier naming specification. The attribute name must be wrapped in quotation marks.
};

1.3 access to attributes

You can use point syntax to access the value of a specified key in an object.

xiaoming.name;		// 'Xiao Ming'
xiaoming.age;		// 12
xiaoming.hobbys;	// ['football', 'swimming', 'programming'] 

If the attribute name does not conform to the JS identifier naming convention, it must be accessed in square brackets.

xiaoming['favorite-book'];	// 'schuck and beta '

If the property name is stored as a variable, it must be in square brackets.

var obj = {
    a: 1,
    b: 2,
    c: 3
};

var key = 'b';
console.log(obj.key);	// undefined
console.log(obj[key]);	// 2

1.4 change of attributes

You can change an attribute by reassigning it directly using the assignment operator.

var obj = {
    a: 10
};
obj.a = 30;
obj.a++;

1.5 creation of attributes

If the object itself does not have a property value, this property will be created when it is assigned with dot syntax.

var obj = {
    a: 10
};
obj.b = 40;

1.6 deletion of attributes

If you want to delete the attributes of an object, you need to use the delete operator.

var obj = {
    a: 1,
    b: 2
};
delete obj.a;

2, Object method

2.1 cognitive methods

If a property value is a function, it is also called the "method" of the object.

var xiaoming = {
    name: 'Xiao Ming',
    age: 12,
    sex: 'male',
    hobbys: ['Football', 'Swimming', 'programming'],
    'favorite-book': 'Schunck and betta',
    // sayHello method
    sayHello: function () {
		console.log('Hello, I'm Xiao Ming. I'm 12 years old. I'm a boy');
	}
};

2.2 method call

Use point syntax to call methods on objects.

xiaoming.sayHello();

2.3 methods and functions

Methods are also functions, but methods are "function properties" of objects, which need to be called with objects.

After formally learning what is "method", we can deeply understand the writing forms of some functions we learned before, such as:

console.log();
Math.ceil();

2.4 object traversal

Similar to traversing arrays, objects can also be traversed. Traversing objects requires a for... in... Loop.

Use the for... in... Loop to traverse each key of the object.

In the subsequent ES6 related courses, we will also learn the new way of object traversal.

[for... in... Cycle]

// k: Loop variable, which becomes each key of the object in turn
// obj: object to traverse
for (var k in obj) {
    console.log('attribute' + k + 'The value of is' + obj[k]);
}

[case]

var obj = {
    a: 11,
    b: 22,
    c: 88
};
for (var k in obj) {
    console.log('object obj Properties of' + k + 'The value of is' + obj[k]);
}

/*
The value of attribute a of object obj is 11
 The value of attribute b of object obj is 22
 The value of attribute c of object obj is 88
*/

3, Deep and shallow cloning of objects

3.1 review basic type values and reference type values

Remember the basic type values and reference type values we learned before?

give an exampleWhen var a = b variable passes valueWhen compared with = =
Basic type valueNumber, string, Boolean, undefined, nullGenerate a new copy in memoryCompare values for equality
Reference type valueObjects, arrays, etcInstead of generating a new copy in memory, let the new variable point to the same objectCompare whether the memory addresses are the same, that is, compare whether they are the same object

3.2 objects are reference type values

Object is a reference type value, which means:

You cannot clone an object with a syntax like var obj2 = obj1.

When using = = or = = = to compare objects, we compare whether they are the same object in memory, not whether the values are the same.

[case]

// Example 1
var obj1 = {
    a: 1,
    b: 2,
    c: 3
};
var obj2 = {
    a: 1,
    b: 2,
    c: 3
};
console.log(obj1 == obj2);      // false
console.log(obj1 === obj2);     // false

console.log({} == {});          // false
console.log({} === {});         // false

// Example 2
var obj3 = {
    a: 10
};
var obj4 = obj3;
obj3.a++;
console.log(obj4);              // {a: 11}
console.log(obj3 == obj4);      // true

3.3 shallow cloning of objects

Review what is shallow cloning: only the "surface layer" of the object is cloned. If some attribute values of the object are reference type values, they are not cloned further, but their references are passed.

Shallow cloning of objects can be achieved by using the for... in... Loop.

[case]

var obj1 = {
    a: 1,
    b: 2,
    c: [44, 55, 66]
};

// var obj2 = obj1;   This is not cloning!!!!

// Implement shallow cloning
var obj2 = {};
for (var k in obj1) {
    // Every time a k attribute is traversed, a k attribute with the same name is added to obj2
    // The value is the same as the k attribute value of obj1
    obj2[k] = obj1[k];
}

// Why shallow cloning? For example, if the value of the c attribute is a reference type value, the c attributes of obj1 and obj2 are essentially the same array in memory and have not been cloned.
obj1.c.push(77);
console.log(obj2);                  // The c attribute of obj2 will also be added to the array
console.log(obj1.c == obj2.c);      // True, true proves that the array is the same object

3.4 deep cloning of objects

Review what deep cloning is: clone the whole picture of objects. You can clone objects regardless of whether their attribute values are reference type values or not.

Similar to deep cloning of arrays, deep cloning of objects requires recursion.

Deep cloning algorithm is often investigated during the interview, which must be mastered.

[case]

var obj1 = {
    a: 1,
    b: 2,
    c: [33, 44, {
        m: 55,
        n: 66,
        p: [77, 88]
    }]
};

// Deep cloning
function deepClone(o) {
    // To determine whether o is an object or an array
    if (Array.isArray(o)) {
        // array
        var result = [];
        for (var i = 0; i < o.length; i++) {
            result.push(deepClone(o[i]));
        }
    } else if (typeof o == 'object') {
        // object
        var result = {};
        for (var k in o) {
            result[k] = deepClone(o[k]);
        }
    } else {
        // Basic type value
        var result = o;
    }
    return result;
}


var obj2 = deepClone(obj1);
console.log(obj2);

console.log(obj1.c == obj2.c);      // false

obj1.c.push(99);
console.log(obj2);                  // obj2 remains unchanged, because there is no "broken ties" phenomenon

obj1.c[2].p.push(999);
console.log(obj2);                  // obj2 remains unchanged, because there is no "broken ties" phenomenon

4, Cognitive context

4.1 what is context

Garbage sorting is a very good habit and deserves praise.

Turn off the lights at will. It's a very good habit and worthy of praise.

After class review, this is a very good habit, worthy of praise.

Early to bed and early to rise, this is a very good habit, worthy of praise.

4.2 function context

You can use the this keyword in a function, which represents the context of the function.

Similar to "this" in Chinese, the specific meaning of this in the function must be judged by the "preface and postscript" when calling the function.

4.3 this in function

var xiaoming = {
    nickname: 'Xiao Ming',
    age: 12,
    sayHello: function () {
        console.log('I am' + this.nickname + ',I' + this.age + 'Years old');
    }
};
xiaoming.sayHello();

// I'm Xiao Ming. I'm 12 years old
var xiaoming = {
    nickname: 'Xiao Ming',
    age: 12,
    sayHello: function () {
        console.log('I am' + this.nickname + ',I' + this.age + 'Years old');
    }
};
var sayHello = xiaoming.sayHello;	// The function is "raised" and stored as a variable separately
sayHello();		// Call this function directly with parentheses instead of object punctuation

// I'm undefined. I'm undefined

4.4 the context of the function is determined by the calling method

If the same function is called in different forms, the context of the function is different.

  • Case 1: the object management calls the function, and this in the function refers to the managed object
xiaoming.sayHello();
  • Case 2: parentheses directly call the function, and this in the function refers to the window object
var sayHello = xiaoming.sayHello;
sayHello();

[case]

var obj = {
    a: 1,
    b: 2,
    fn: function() {
        console.log(this.a + this.b);
        /*
        Excuse me, here are two this What do you mean?
        Correct answer: I don't know!
        Reason: the context of a function can only be determined when it is called.
    }
};

obj.fn();	//3

var fn = obj.fn;	// It refines the function itself, not the execution result of the function, so you can't add ()
fn();		//NaN

5, Context rules

5.1 the context of a function is determined by the way the function is called

The context of a function (this keyword) is determined by how the function is called, and function is the "runtime context" policy.

If the function is not called, the context of the function cannot be determined.

5.2 rule 1

Rule 1: if an object calls its method function, the context of the function is the object of the management.

object.method()

[example of rule 1 topic - sub topic 1]

function fn() {
    console.log(this.a + this.b);
}

var obj = {
    a: 66,
    b: 33,
    fn: fn
};

obj.fn();	// 99	
// Constitute the object In the form of method (), rule 1 applies

[example of rule 1 topic - sub topic 2]

var obj1 = {
    a: 1,
    b: 2,
    fn: function() {
        console.log(this.a + this.b);
    }
};

var obj2 = {
    a: 3,
    b: 4,
    fn: obj1.fn		// The fn method in obj2 points to the fn method in obj1, that is, the fn method has only one copy in memory but is pointed to twice
};

obj2.fn();	// 7
// Constitute the object Method (), using rule 1

[example of rule 1 topic - sub topic 3]

function outer() {
    var a = 11;
    var b = 22;
    // Returns an object
    return {
        a: 33,
        b: 44,
        fn: funtion() {
        	console.log(this.a + this.b);
    	}
    };
}

outer().fn();	// 77
// Constitute the object In the form of method (), rule 1 applies

[example of rule 1 topic - sub topic 4]

funtion fun() {
    console.log(this.a + this.b);
}
var obj = {
    a: 1,
    b: 2,
    c: [{
        a: 3,
        b: 4,
        c: fun
    }]
};
var a = 5;
obj.c[0].c();	// 7	
// Constitute the object In the form of method (), rule 1 applies

5.3 rule 2

Rule 2: if the parentheses call the function directly, the context of the function is the window object.

function()

[example of rule 2 topic - sub topic 1]

var obj1 = {
    a: 1,
    b: 2,
    fn: function() {
        console.log(this.a + this.b);
    }
};

var a = 3;
var b = 4;

var fn = obj1.fn;	// Give the reference of the function to the variable store
fn();	// 7
// The form of the constituent function () applies to rule 2

[example of rule 2 - sub question 2]

function fun() {
    return this.a + this.b;
}
var a = 1;
var b = 2;
var obj = {
    a: 3,
    b: fun(),	// The execution result of the fun function is assigned to b, and rule 2 applies
    fun: fun	// Reference to fun function
};
var resulr = obj.fun();		// Applicable rule 1
console.log(result);	// 6

5.4 rule 3

Rule 3: the array (class array object) is called by a function, and the context is this array (class array object).

array[subscript]()

[example of rule 3 topic - sub topic 1]

var arr = ['A', 'B', 'C', function() {
    console.log(this[0]);
}];
arr[3]();	// A
// Applicable rule 3

[class array object]

What is a class array object: all objects whose key names are natural number sequences (starting from 0) and have the length attribute.

The arguments object is the most common class array object, which is a list of arguments to a function.

[example of rule 3 topic - sub topic 2]

function fun() {
    arguments[3]();	// Applicable rule 3
}
fun('A', 'B', 'C', function() {
    console.log(this[1]);
});
// B

5.5 Rule 4

Rule 4: for functions in IIFE, the context is a window object.

(function() {
 })();

[Rule 4 title - examples]

var a = 1;
var obj = {
    a: 2,
    fun: (funciton() {
          var a = this.a;
          return function() {
    	  	  console.log(a + this.a);	// 1 + 2
		  }
     })()	// Applicable rule 4
};
obj.fun();	// Applicable rule 1
// 3

5.6 Rule 5

Rule 5: the timer and delayer call the function, and the context is the window object.

setInterval(function, time);
setTimeout(function, time);

[example of Rule 5 topic - sub topic 1]

var obj = {
    a: 1,
    b: 2,
    fun: funciton() {
    	console.log(this.a + this.b);
	}
}
var a = 3;
var b = 4;

setTimeout(obj.fun, 2000);	// 7
// Applicable rule 5

[example of Rule 5 topic - sub topic 2]

var obj = {
    a: 1,
    b: 2,
    fun: function() {
        console.log(this.a + this.b);
    }
}
var a = 3;
var b = 4;
setTimeout(funciton() {
		obj.fun(); // Rule 1 is applicable. Reason: at this time, setTimeout does not directly call obj Instead of fun (), anonymous functions are called directly
}, 2000);

5.7 rule 6

Rule 6: the context of the event handler is the DOM element that binds the event.

DOM element.onclick = function() {
};

[rule 6 - small case 1]

Please achieve the effect: click which box, which box will turn red. It is required to use the same event handler function.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            float: left;
            border: 1px solid #000;
            margin-right: 10px;
        }
    </style>
</head>
<body>
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>

<script>
    function setColorToRed() {
        this.style.backgroundColor = 'red';
    }

    var box1 = document.getElementById('box1');
    var box2 = document.getElementById('box2');
    var box3 = document.getElementById('box3');

    box1.onclick = setColorToRed;
    box2.onclick = setColorToRed;
    box3.onclick = setColorToRed;
</script>
</body>
</html>

[rule 6 - small case 2]

Please achieve the effect: click which box and which box will turn red after 2000 milliseconds. It is required to use the same event handler function.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            float: left;
            border: 1px solid #000;
            margin-right: 10px;
        }
    </style>
</head>
<body>
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>

<script>
    function setColorToRed() {
        // Back up the context (because the timer and delayer call the function, and the context is a window object, back up the context first, using self or that or _this)
        var self = this;
        setTimeout(function () {
            self.style.backgroundColor = 'red';
        }, 2000);
    }

    var box1 = document.getElementById('box1');
    var box2 = document.getElementById('box2');
    var box3 = document.getElementById('box3');

    box1.onclick = setColorToRed;
    box2.onclick = setColorToRed;
    box3.onclick = setColorToRed;
</script>
</body>
</html>

6, call and apply

6.1 call and apply can specify the context of the function

function sum() 
    alert(this.chinese + this.math + this.english);
}

var xiaoming = {
    chinese: 80,
    math: 95,
    english: 93
};

sum.call(xiaoming); Or sum apply(xiaoming);

  • Function Call (context);
  • Function Apply (context);

Of course, this is OK:

function sum() {
    alert(this.chinese + this.math + this.english);
}

var xiaoming = {
    chinese: 80,
    math: 95,
    english: 93,
    sum: sum
};

xiaoming.sum();

6.2 difference between call and apply

function sum(b1, b2) {
    alert(this.c + this.m + this.e + b1 + b2);
}

var xiaoming = {
    c: 80,
    m: 95,
    e: 93
};

sum.call(xiaoming, 5, 3);		// call to list parameters with commas
sum.apply(xiaoming, [5, 3]);	// apply writes the parameters to the array

6.3 call or apply?

function fun1() {
    fun2.apply(this, arguments);	// arguments is an array. You can only use apply
}

function fun2(a, b) {
    alert(a + b);
}

fun1(33, 44);	// 77

6.4 summary of context rules

rulecontext
Object Function ()object
Function ()window
Array [subscript] ()array
IIFEwindow
timerwindow
DOM event handlerBinding DOM elements
call and applyArbitrary designation

7, Call the function with the new operator

Now let's learn a new way to call a function: the new function ()

You may know that the new operator is closely related to "Object-Oriented", but now we don't discuss its "Object-Oriented" meaning, but first clarify the execution steps and context of calling the function with new.

7.1 four steps of calling function with new

JS stipulates that calling a function using the new operator will carry out "four steps":

  1. A blank object is automatically created in the function body
  2. The context of the function (this) points to this object
  3. The statements in the function body are executed
  4. The function automatically returns the context object, even if the function does not have a return statement

7.2 four step explanation

function fun() {
    this.a = 3;
    this.b = 5;
}

var obj = new fun();
console.log(obj);

[step 1: a blank object will be automatically created in the function body]

[step 2: the function context (this) will point to this object]

[step 3: execute the statements in the function body]

After that, the object is no longer empty.

[step 4: the function will automatically return the context object, even if the function does not have a return statement]

The execution result is: {a: 3, b: 5}

[case]

function fun() {
    this.a = 3;
    this.b = 6;
    var m = 34;
    if (this.a > this.b) {
        this.c = m;
    } else {
        this.c = m + 2;
    }
}

var obj = new fun();
console.log(obj);

// fun { a: 3, b: 6, c: 36 }

7.3 summary of context rules

rulecontext
Object Function ()object
Function ()window
Array [subscript] ()array
IIFEwindow
timerwindow
DOM event handlerBinding DOM elements
call and applyArbitrary designation
Call function with newObjects created secretly

8, Constructor

8.1 what is a constructor

Let's make a small improvement on the previously written function:

// Receive three parameters
function People(name, age, sex) {
    // Bind an attribute with the same name on this
    this.name = name;
    this.age = age;
    this.sex = sex;
}

// Pass in three parameters
var xiaoming = new People('Xiao Ming', 12, 'male');
var xiaohong = new People('Xiao Hong', 10, 'female');
var xiaogang = new People('Xiao Gang', 13, 'male');

console.log(xiaoming);	// People {Name: 'Xiao Ming', age: 12, sex: 'male'}
console.log(xiaohong);	// People {Name: 'Xiaohong', age: 10, sex: 'female'}
console.log(xiaogang);	// People {Name: 'Xiao Gang', age: 13, sex: 'male'}
  • Call a function with new, which is called "constructor". Any function can be a constructor, just call it with new
  • As the name suggests, the constructor is used to "construct a new object". Its internal statements will add several properties and methods to the new object to complete the initialization of the object
  • The constructor must be called with the new keyword, otherwise it cannot work normally. Because of this, the developer agreed that the first letter of the constructor should be capitalized when naming

Note: whether a function is a constructor depends on whether it is called with new. As for the initial capitalization of the name, it is entirely the customary convention of developers.

8.2 call the constructor without new

function People(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
}

People('Xiao Ming', 12, 'male');
People('Xiao Hong', 10, 'female');
People('Xiao Gang', 13, 'male');

8.3 this in the constructor is not the function itself

Four step principle!!!

function People(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
}

var xiaoming = new People('Xiao Ming', 12, 'male');
var xiaohong = new People('Xiao Hong', 10, 'female');
var xiaogang = new People('Xiao Gang', 13, 'male');

8.4 trying to add methods to objects

function People(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.sayHello = function() {
        console.log('I am' + this.name + ',I' + this.age + 'Years old');
    };
}

var xiaoming = new People('Xiao Ming', 12, 'male');
var xiaohong = new People('Xiao Hong', 10, 'female');
var xiaogang = new People('Xiao Gang', 13, 'male');
xiaoming.sayHello();
xiaohong.sayHello();
xiaogang.sayHello();

/*
I'm Xiao Ming. I'm 12 years old
 I'm Xiao Hong. I'm 10 years old
 I'm Xiao Gang. I'm 13 years old
*/

9, Classes and instances

[classes are like "blueprints"]

Like the blueprint, the class only describes which properties and methods the object will have, but does not specify the value of the property.

[instance is a specific object]

[constructor and class]

  • Java and C + + are "Object-Oriented" languages
  • JavaScript is an "object-based" language
  • The constructor in JavaScript can be compared with the "class" in OO language. The writing method is indeed similar, but it is essentially different from the real OO language. In subsequent courses, we will also see the unique prototype characteristics completely different from JS and other OO languages.

10, Prototype and prototype chain lookup

10.1 what is prototype

Any function has a prototype attribute. Prototype means "prototype" in English.

The value of the prototype attribute is an object. By default, it has the constructor attribute to refer back to the function.

The prototype attribute of an ordinary function is useless, while the prototype attribute of a constructor is very useful.

The prototype property of the constructor is the prototype of its instance.

10.2 the prototype of the constructor is the prototype of the instance

10.3 prototype chain search

JavaScript stipulates that an instance can manage the properties and methods of accessing its prototype, which is called "prototype chain lookup".

10.4 hasOwnProperty

The hasOwnProperty method can check whether an object really "owns" a property or method.

xiaoming.hasOwnProperty('name');		// true
xiaoming.hasOwnProperty('age');			// true
xiaoming.hasOwnProperty('sex');			// true
xiaoming.hasOwnProperty('nationality');	// false

10.5 in

The in operator can only check whether a property or method can be accessed by an object, not whether it is its own property or method.

'name' in xiaoming			// true
'age' in xiaoming			// true
'sex' in xiaoming			// true
'nationality' in xiaoming	// true

11, Add method on prototype

Before 11.1, we wrote methods to objects

In the previous courses, we added the methods directly to the examples:

function People(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.sayHello = function() {	// Method is added directly to the instance
        console.log('I am' + this.name);
    }
}

The disadvantage of adding methods directly to instances: each instance and the method function of each instance are different functions in memory, resulting in a waste of memory.

Solution: write the method on the prototype.

11.2 the method should be written on the prototype

function People(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
}

People.prototype.sayHello = function() {
    console.log('I am' + this.name);
}

People.prototype.sleep = function() {
    console.log(this.name + 'Start sleeping.zzzz');
}

12, End of prototype chain

[end of prototype chain]

[about prototype chain of array]

Topics: Javascript Front-end