Reference Type
Reference types mainly include: Object type, Array type, Date type, RegExp type, Function type, etc.
When reference types are used, an object (instance) needs to be generated from them. In other words, a reference type is equivalent to a template. When we want to use a certain reference type, we need to use this template to generate an object for use, so the reference type is sometimes called object definition.
For example, we need to generate a person object to define someone's personal information and behavior, so we need to rely on the Object type:
var person = new Object();person.name = "jiangshui";person.sayName = function(){ console.log(this.name);}The above person object is defined by the "template" using the new operator using the Object type. After that, you can add attribute name and method sayName to this object. Properties and methods are "functions" of Object types, so objects created through reference types such as Object can be used.
Creating an object does not necessarily require the use of the new operator. There are some types that can be simplified in creating. For example, creating an object of type Object like above, you can also use the following two methods:
var person = {};person.name = "jiangshui";person.sayName = function(){ console.log(this.name);}or
var person = { name : "jiangshui", sayName : function(){ console.log(this.name); }};The function of the {} operator is the same as new Object(), simplifying operations. There are some differences in the above two writing methods. The first is "append", that is, in the previous definition, continue to add attributes or methods. If the attribute method of the same name already exists before, it will be overwritten. The second type is "replacement", which means that regardless of whether the properties and methods of the person object are defined before, this method will replace the previously defined content with the newly defined content. Because the object generated by the reference type is a region stored in memory, and then its pointer is saved in a certain variable (person), the second way of writing is to generate a new object (new memory area), and then point the person variable to the new memory area, so the previous one is replaced. Understanding this is crucial to the later understanding.
The usage of other reference types is roughly the same, such as the Array type, which can also be used to generate objects or directly define them. After generating an array object, you can store the information content in the format of the array. In addition, the object will get the methods defined in the Array type, such as push, shift, sort, etc., and you can call these methods, such as:
var colors = [];colors.push('red','green');console.log(colors);The above code creates an array-type object through the Array type, then calls the push method defined previously in the Array type, adds two values red and green to the object, and finally prints it out on the console and you can see it.
call and apply methods
These two methods are provided by the Function type, which means they can be used on functions. The function of call is the same as the apply method, which is that it can expand the scope of function operation. The difference is that when using call, the parameters passed to the function must be listed one by one, but the apply method does not use it. In this way, you can decide to use call or apply according to the requirements of your own function.
What does the scope of the expansion function operation mean? You will understand by giving an example.
You can understand this way that the function is wrapped in a container (scope), and there are some variables or other things in this container. When the function runs, these variables are called, etc., you will find this thing in the current container. This container actually wraps a larger container outside. If the current small container does not have it, the function will search in the larger container, and so on, and find the largest container window object. However, if the function is running in the current small container, there are corresponding variables, etc. in the small container, even in the large container, the function will still call it in its own container.
The call and apply methods are to solve this problem and break through the limitations of containers. As for the previous example:
var person = { name : "jiangshui", sayName : function(){ console.log(this.name); }};After opening the Chrome Console, paste it in and execute it, and then execute person.sayName() to see
At this time, person is a container, which creates a sayName method (function). When executing, it must be executed under the person scope. When directly executed at the bottom, that is, execution under the scope of window will cause an error not defined because the sayName method is not defined below window. The this pointer inside is a special thing, which points to the current scope. The meaning of this.name is to call the name value below the current scope.
Next, we add a name attribute to the window object:
window.name = "yujiangshui";
Or directly
name = "yujiangshui";
Because window is the largest container, window can be omitted. All defined attributes or variables are attached to window. If you don't believe it, you can see:
Now we want to run the sayName method in the person small container under the large container of window. We need to use call or apply to expand the scope of the sayName method. Execute the following statement:
person.sayName.call(window);
or
person.sayName.call(this);
The output results are the same. You can also use apply to see the effect, because this demo is too simple and does not require passing parameters, so the functions of call and apply are completely consistent.
Let me explain the above code. SayName is first an instance of the Function type, which has the call method and the apply method. Since the call and apply methods are Function methods, we need to call person.sayName.call(window) in this way instead of person.sayName().call(window) and so on.
Then the parameters of the call and apply methods are a scope (object), indicating that the previous function is run under the scope passed in. After passing the window object in, this.name in the sayName method points to window.name, so the scope is expanded.
Why does passing window and this have the same effect? Because the current location of executing this function is window, as mentioned earlier, this pointer points to the current scope, so this pointer points to window, so it is equal to window.