Object-Oriented - A Stepping Stone to the Advanced Stage of JavaScript

foreword

In computer programming, object is a very important concept. It can help us better organize and manage data, and make code more modular and reusable. An object can store multiple key-value pairs, each key-value pair represents an attribute, and the attribute can be a value of a basic type or another object. Through objects, we can define and call methods, operate on properties or implement specific functions.

The idea of ​​object-oriented programming emphasizes organizing and managing code through objects and classes, making it easier to understand and maintain. In fact, decomposing problems and solutions into objects is a very natural and intuitive way, and it is also the key to achieve code reuse and modularization.

In the following studies, we will understand and master these concepts more deeply, and practice and consolidate the knowledge we have learned through small cases. Let's embark on a learning journey together!

1. Recognize the object

1. What is an object

  • Concept: Object (object) is a collection of "key-value pairs" , representing the mapping relationship between attributes and values
    insert image description here

  • Syntax: k and v are separated by colons , each group of k:v is separated by commas, and commas are not required after the last k:v pair

    • If the property key name of the object does not conform to the JS identifier naming convention, the key name must be wrapped in quotation marks
    • For example: 'favorite-book':'舒克和贝塔'there is a dash in the attribute name, which does not conform to the ]S identifier naming convention, and the attribute name must be wrapped in quotation marks
  • Access to object properties

    • You can use " dot syntax" to access the value of the specified key in the object

      xiaoming.name;//小明
      xiaoming.age;//12
      xiaoming.hobbys;//['足球',游泳','编程]
      
    • If the attribute name does not conform to the ]S identifier naming convention, it must be accessed with square brackets

      xiaoming['favorite-book'];//舒克和贝塔
      
    • If the attribute 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
      
  • property change

    • Directly use the assignment operator to re-assign a property to change the property
      var obj ={
              
              
      	a:10
      }
      obj.a = 30;  //将obj里a的值改成了30
      ob].a++;    // a = 31
      
  • attribute creation

    • If the object itself does not have a property value, the property will be created when the dot syntax is used to assign a value
      var obj ={
              
              
      	a:10
      };
      obj.b = 40;  //在obj对象中创建了b:40这个键值对
      
  • property deletion

    • If you want to delete a property of an object, you need to use the delete operator

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

2. Object methods

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

    varxiaoming = {
          
          
    	sayHello:function(){
          
               //sayHello方法
    	 	console.log('你好,我是小明,今年12岁,我是个男生');
    	 	}
    }
    
  • Calling a function with dot methodxiaoming.sayHello();

  • The method is also a function , but the method is the "function attribute" of the object, and it needs to be called by the object

3. Object traversal

  • With the for ... in ... loop, you can iterate over each key of the object
    insert image description here

4. Deep and shallow cloning of objects

  • When the object is a reference type value
    • An object cannot be var obj1 = obj2cloned using syntax like this
    • When using == or === to compare objects, the comparison is whether they are the same object in memory , not whether the comparison values ​​are the same
  • shallow clone
    • Shallow cloning of objects can be achieved by using the for ...in... cycle
  • Deep clone
    • Similar to the type of array, deep cloning of objects requires the use of recursion

         var obj1 = {
              
              
            a:1,
            b:2,
            c:[33,44,{
              
              
              m:55,
              n:66,
              p:[77,88]
            }]
          };
          // 定义一个深克隆函数
          function  deepClone(o){
              
              
            // 判断o是对象还是数组,必须先判断是不是数组,因为数组的类型也是对象
            if(Array.isArray(o)){
              
              
                //数组
              var result = [];
              for(var i=0;i < o.length;i++){
              
              
                result.push(deepClone(o[i]));
              }
            }else if(typeof o == 'object'){
              
              
                // 对象
              var result = {
              
              };
              for (var k in o){
              
              
                result[k] = deepClone(o[k])
              }
            }else{
              
              
                //基本类型值
              var result = o;
            }
            return result;
          }
          var obj2 = deepClone(obj1);
          console.log(obj2);
          
          // 测试一下
          console.log(obj1 === obj2); //false
          
          obj1.c.push(99);
          console.log(obj2);  //obj2是不变的,因为没有'藕断丝连'的现象
        
      

2. Know the function context

  • The context of the function ( this keyword) is determined by the calling method ; the same function is called in different forms, and the context of the function is different

    var xiaoming = {
          
          
    	nickname:小明,
    	age:12,
    	sayHello = function (){
          
          
    		console..log('我是'+this.nickname+',我'+this.age+'岁了)}
    };
    
    • Scenario 1: The function is called by the object dot, and this in the function refers to the dotted object

      xiaoming.sayHello();
      
    • Case 2: The parentheses directly call the function, and this in the function refers to the window object

      var sayHello = xiaoming.sayHello;
      sayHello();
      
  • function is the " runtime context " strategy

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

1. Context rules for functions★

insert image description here

  • Rule①

    • Object dot calls its method function, then the context of the function is the dotted object
    • 对象.方法();
  • Rule ②

    • The parentheses call the function directly, and the context of the function is the window object
    • 函数();
  • Rule ③

    • The array (array-like object) enumerates the function to call, and the context is this array (array-like object)
      • What is an array-like object: an object whose key name is a sequence of natural numbers (starting from 0) and has a length attribute
      • The arguments object is the most common array-like object, which is the actual parameter list of the function
    • 数组[下标]();
  • Rule ④

    • Function in IIFE, context is window object

      (function(){
              
              
      
      })();
      
  • Rule ⑤

    • The timer and delayer call the function, the context is the window object
    • setInterval(函数,时间);
    • setTimeout(函数,时间);
  • Rule ⑥

    • The context of the event handler is the DOM element to which the event is bound
      DOM元素.onclick=function(){
              
              
      }
      

2. call and apply ★

  • call and apply can specify the context of the function
  • 函数.ca11(上下文);To list parameters with commas
  • 函数.apply(上下文);To write the parameters to the array

3. Constructor

1. Call the function with the new operator

  • "Four Steps"

    • 1) A blank object is automatically created in the function body
    • 2) The context (this) of the function will point to this object
    • 3) The statement in the function body will be executed
    • 4) The function will automatically return the context object, even if the function does not have a return statement

2. Classes and instances

insert image description here

3. Constructors and 'classes'

  • Java, C++, etc. are " object-oriented " (object-oriented) languages

  • JavaScript is an " object- based " language

  • The constructor in JavaScript can be compared to the "class" in OO language . The writing method is indeed similar, but it is still fundamentally different from the real OO language.

4. Prototype and prototype chain

1. Prototype and prototype chain search★

  • Any function has a prototype attribute , and prototype means "prototype"
  • The value of the prototype property is an object, which by default has the constructor property pointing back to the function
    insert image description here
  • The prototype attribute for ordinary functions is useless, but the prototype attribute for constructors is very useful
    • The prototype property of a constructor is the prototype of its instance
      insert image description here
            console.log(xiaoming.__proto__ === People.prototype); //true 
    
  • prototype chain lookup
    • JavaScript stipulates that an instance can access the properties and methods of its prototype
  • hasOwnProperty() method
    • Can check whether the object really "owns" a property or method
  • in operator
    • You can only check whether a certain property or method can be accessed by the object, you cannot check whether it is your own property or method

2. Add methods on the prototype

  • Disadvantages 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: Add the method to the prototype
    insert image description here

3. The end of the prototype chain

  • The end of the prototype chain of all things - Object.prototype

The overall path of the prototype chain

  • code example

      function People(){
          
          
    
      }
      var xiaoming = new People();
      console.log(xiaoming.__proto__.__proto__ === Object.prototype);	//true
      console.log(Object.prototype.__proto__);							 //null
    
      console.log(Object.prototype.hasOwnProperty('hasOwnProperty'));	 //true
    
    
  • array's prototype chain

    insert image description here

 var arr = [22,33,4,555];

  console.log(arr.__proto__ === Array.prototype);            //true
  console.log(arr.__proto__ .__proto__=== Object.prototype); //true
  console.log(Array.prototype.hasOwnProperty('push'));        //true

4. Inheritance★

  • Inheritance describes the "is a kind of" relationship between two classes . For example, a student "is a kind of" person, so an inheritance relationship is formed between a human being and a student class

  • People is the " parent class " (or "super class", "base class"); Student is the " subclass " (or "derived class")

  • The subclass enriches the parent class, making the class description more specific and detailed

  • example

  • Inheritance through the prototype chain
    • Let the prototype of the subclass constructor point to an instance of the parent class:Student.prototype = new People();

insert image description here

		 //父类:人类
		  function People(name,age,sex){
    
    
		    this.name = name;
		    this.age = age;
		    this.sex = sex;
		  }
		  People.prototype.sayHello = function (){
    
    
		    console.log('你好,我是'+this.name +'我今年'+this.age+'岁了');
		  }
		  People.prototype.sleep = function (){
    
    
		    console.log(this.nam+'开始睡觉,zzzz');
		  }
		// 子类:学生
		  function Student(name,age,sex,school,studentNumber){
    
    
		    this.name = name;
		    this.age = age;
		    this.sex = sex;
		    this.school = school;
		    this.studentNumber = studentNumber;
		  }
		  //关键语句,实现继承
		  Student.prototype = new People();
		  Student.prototype.study = function (){
    
    
		    console.log(this.name + '正在学习');
		  }
		  Student.prototype.exam = function (){
    
    
		    console.log(this.name+'正在考试,加油!');
		  }
		
		  //实例化
		  var hanmeimei = new Student('韩梅梅',12,'女','CSDN大学',123456);
		  hanmeimei.study();
		  hanmeimei.sayHello();

Five, rising to object-oriented

  • The essence of object-oriented: define different classes, let the instances of the class work
  • Object-oriented advantages: clearer program writing, tighter code structure, more robust code and easier maintenance
  • Occasions where object-oriented is often used: occasions that require encapsulation and reusability (component thinking)

1. Small case of traffic lights

  • Using object-oriented programming, you can solve the problem of a large number of conflicting traffic lights with " component " thinking

  • Object-oriented programming, the most important thing is to write classes

  • TrafficLight class

    • Attributes: own current color color, own DOM element dom
    • Method: Initialize init(), switch color changeColor(), bind event bindEvent()
  • Code example:

     #box img{
          
          
                width: 80px ;
            }
    
    <div id="box" ></div>
    
    //定义红绿灯类,构造函数
            function TrafficLight(){
          
          
                //颜色属性,一开始都是红色
                //红色1,黄色2,绿色3
                this.color = 1;
                //调用自己的初始化方法
                this.init();
                //绑定监听
                this.bindEvent();
            }
            //初始化方法
            TrafficLight.prototype.init = function (){
          
          
                // alert('我是init方法');
                //创建自己的DOM
                this.dom = document.createElement('img');
                this.dom.src = this.color+'.jpg';
                box.appendChild(this.dom);
            }
            // 绑定监听
            TrafficLight.prototype.bindEvent = function (){
          
          
                //备份上下文,这里的this指的是JS实例
                var self = this;
                //当自己的dom被点击时
                this.dom.onclick = function (){
          
          
                    // 当被点击时,调用自己的changeColor方法
                    self.changeColor();
                };
            }
            // 改变颜色
            TrafficLight.prototype.changeColor = function (){
          
          
                // 改变自己的color属性,从而有一种"自治"的感觉,自己管理自己不干扰别的红绿灯
                this.color++;
                if(this.color == 4){
          
          
                    this.color = 1;
                }
                // 光color属性变化没用,还要更改自己的dom中src属性,才能更换图片
                this.dom.src = this.color+'.jpg';
            };
    
    
    
            // 得到盒子
            var box = document.getElementById('box');
    
            // 实例化100个
            var count = 100;
    
            // 当count-- 为0的时候,判断为false,跳出循环
            while(count--){
          
          
                new TrafficLight();
            }
    

2. Small colorful ball case

  • Properties of the Boll class
    insert image description here

  • Methods of the Boll class

    • init() initialization method
    • update() update method
  • Realize the animation of multiple small balls

    • Put each ball instance in the same array
      • [{ball instance},{ball instance},{ball instance},{ball instance}]
    • You only need to use a timer to traverse each ball in each frame and call their update method
  • Code example:

     body{
          
          
            background-color: black;
          }
          .ball{
          
          
            position: absolute;
            border-radius: 50%;
          }
    
     //小球类
      function Ball(x,y){
          
          
        //属性x,y表示的是圆心的坐标
        this.x = x;
        this.y = y;
        //透明的
        this.opacity = 1;
        do{
          
          
            // 这个小球的x增量和y的增量
            this.dX = parseInt(Math.random()*20)-10;
            this.dY = parseInt(Math.random()*20)-10;
        }while(this.dX === 0 || this.dY === 0)
    
        // 小球的背景颜色
        this.color = colorArr[parseInt(Math.random()*colorArr.length)];
        // 小球半径
        this.r = 20;
        // 初始化
        this.init();
        // 把自己推入数组,注意:这里的this不是类本身,而是实例
          ballArr.push(this);
      }
      Ball.prototype.init = function (){
          
          
        //创建自己的dom
        this.dom = document.createElement('div');
        this.dom.className = 'ball';
        this.dom.style.width = this.r *2 +'px';
        this.dom.style.height = this.r *2 +'px';
        this.dom.style.left = this.x - this.r+'px';
        this.dom.style.top = this.y - this.r+'px';
        this.dom.style.backgroundColor = this.color;
        //上树
          document.body.appendChild(this.dom);
      }
    
      // 更新
      Ball.prototype.update = function (){
          
          
          // 位置改变
          this.x += this.dX;
          this.y -= this.dY;
          // 半径改变
          this.r += 0.2;
          // 透明度改变
          this.opacity -= 0.05;
          this.dom.style.width = this.r *2 +'px';
          this.dom.style.height = this.r *2 +'px';
          this.dom.style.left = this.x - this.r+'px';
          this.dom.style.top = this.y - this.r+'px';
          this.dom.style.opacity = this.opacity;
          // 当透明度小于0,就需要从数组中删除自己,DOM元素也要删除自己
          if(this.opacity<0){
          
          
              //从数组中删除自己
              for (var i = 0; i<ballArr.length;i++){
          
          
                  if(ballArr[i] == this){
          
          
                      ballArr.splice(i,1);
                  }
                  //还要删除自己的dom
                  document.body.removeChild(this.dom);
              }
          }
    
      };
    
    
      // 把所有的小球实例都放到一个数组中
      var ballArr = [];
      // 初始颜色数组
      var colorArr = ['#66CCCC','#CCFFCC','#FF99CC','#FF6666','#CC3399','#ff6600']
    
      // 定时器,负责更新所有的小球实例
      setInterval(function (){
          
          
          //遍历数组 ,调用update方法
          for(var i= 0;i<ballArr.length;i++){
          
          
            ballArr[i].update();
          }
      },20);
      // 鼠标指针的监听
      document.onmousemove = function (e){
          
          
          //得到鼠标指针的位置
          var x = e.clientX;
          var y = e.clientY;
          new Ball(x,y);
      }
    
    

Six, JS built-in objects

1. Packaging

  • Instances of Number(), String(), and Boolean() are all object types, and their Primitivevalue properties store their own values
  • The basic type value from new can normally participate in the operation
  • The purpose of wrapper classes is to allow basic type values ​​​​to obtain methods from the prototype of their constructors

2.Math object★

  • Power and square root: Math.pow(), Math.sqrt()

  • Rounding up and down: Math.ceil(), Math.floor()

  • Math.round() method: rounding

    • round to two decimal places
      insert image description here
  • Math.max(): Get the maximum value of the parameter list

    • Use Math.max() to find the maximum value of an array
      • Math.max() requires that the parameter must be "listed", not an array

      • With the apply method, it can specify the context of the function, and pass in "scattered values" as parameters of the function in the form of an array

        var arr = [3,6,9,2];
        var max = Math.max.apply(null,arr);
        console.log(max);  // 9
        
  • Math.min(): Get the minimum value of the parameter list

  • Math.random(): Get a decimal between 0 and 1

    • To get an integer in the interval [a,b], you can use this formula:
      • parseInt(Math.random()*(b-a +1))+a

3.Date object★

  • Use new Date() to get the date object of the current time, which is an object type value
    • Use new Date(2023,6,26) to get the date object of the specified date,
      • Note that the second parameter represents the month, starting from 0, and 6 represents July
    • It can also be written as new Date('2023-07-26')
  • Date object common methods
    insert image description here
  • timestamp
    • The timestamp represents the number of milliseconds from a certain moment on January 1, 1970 at zero o'clock

    • The date object can be turned into a timestamp by the getTime() method or the Date.parse() function

    • By writing new Date (time stamp), the time stamp can be changed into a date object

7. Inheritance and built-in constructors [Expand]

  • built-in constructor

    • JavaScript has many built-in constructors . For example, Array is the constructor of the array type, Function is the constructor of the function type, and Object is the constructor of the object type.
    • The built-in constructor is very useful. All methods of this type are defined on the prototype of its built-in constructor . We can add new methods to this object to expand the functionality of a certain type
    • Number\String\Boollearn is a wrapper class for three basic types of values. Calling them with new can generate "object" versions of basic type values
  • Built-in Constructor Relations

    • Any function can be regarded as Function "new", including Object
      insert image description here
  • With constructors (also known as "fake objects" or "classical inheritance")

    • Advantages: Solve the problem caused by the reference type value contained in the prototype and the inelegant problem of the subclass constructor
    • Principle: Call the superclass constructor inside the subclass constructor , but pay attention to using call() to bind the context
        function People(name,sex,age){
          
          
          this.name = name;
          this.sex = sex;
          this.age = age;
          this.arr = [22,33,44];
        }
        function Student(name,sex,age,school,sid){
          
          
          People.call(this,name,sex,age);  // 借助构造函数
          this.school = school;
          this.sid = sid;
        }
        var xiaoming = new Student('小明','男',12,'CSDN学校',123455);
        console.log(xiaoming);
      </script>
    
  • Composition inheritance (most commonly used)

    • Principle: The technology of borrowing the prototype chain and borrowing the constructor is combined, also called pseudo-classical inheritance
    • Disadvantages: In any case, the constructor of the superclass will be called twice, once when creating the subclass prototype, and once inside the subclass constructor
        //父类
      function People(name,sex,age){
          
          
        this.name = name;
        this.sex = sex;
        this.age = age;
      }
      People.prototype.sayHello = function (){
          
          
          console.log('你好,我是'+this.name+'今年'+this.age+'岁了');
      }
      People.prototype.sleep = function (){
          
          
          console.log(this.name+'正在睡觉');
      }
    
        //子类
      function Student(name,sex,age,school,sid){
          
          
          //借助构造函数
          People.call(this,name,sex,age);
        this.school = school;
        this.sid = sid;
      }
      //实现继承:借助原型链
      Student.prototype = new People();
      Student.prototype.exam = function (){
          
          
          console.log(this.name + '正在考试')
      }
      Student.prototype.sayHello = function (){
          
          
          console.log('敬礼!你好,我是'+this.name+'今年'+this.age+'岁了'+this.school+'的学生');
      }
      var xiaoming = new Student('小明','男',12,'CSDN学校',123455);
      console.log(xiaoming);
      xiaoming.sayHello();
      xiaoming.sleep();
      xiaoming.exam();
    
  • prototypal inheritance

    • Meet Object.creat()
      • IE9+ starts to support the Object.create() method, which can create a new object based on the specified object as a prototype , without resorting to the constructor
      • Example:var obj2 = Object.create(obj1);
        insert image description here
    • Concept: In the case where there is no need to create a constructor, but just want the new object to be "similar" to the existing object, Object.create() can be used, which is called prototypal inheritance
  • parasitic inheritance

    • Write a function that receives a parameter o, returns a new object p with o as the prototype, and adds a prefabricated new method to p
      insert image description here
    • Parasitic inheritance is to write a function that can " enhance the object ". As long as the object is passed into this function, the function will create a new object based on this object and assign a new preset method to the new object.
    • Parasitic inheritance is also a useful pattern in cases where objects are primarily considered rather than custom types and constructors
    • Disadvantages: Using parasitic inheritance to add functions to objects will reduce efficiency due to the inability to achieve function reuse, that is, "the method is not written on the prototype "
  • parasitic compositional inheritance

    • Inherit properties by borrowing constructors
    • Inheritance of methods via a hybrid form of the prototype chain
    • Basic idea: It is not necessary to call the supertype's constructor to specify the subtype's prototype, all we need is a copy of the supertype's prototype. Essentially, use parasitic inheritance to inherit the prototype of the supertype and then assign the result to the prototype of the subtype
  • instanceof operator

    • The instanceof operator is used to detect "whether an object is an instance of a certain class", such as: xiaoming instanceof Student
    • Underlying mechanism: Check whether the Student.prototype attribute is on the prototype chain of xiaoming (how many layers are fine, as long as it is there)

Guess you like

Origin blog.csdn.net/weixin_40845165/article/details/131920451