In-depth understanding of javascript functions series 3 - properties and methods

previous words

Functions are special objects in javascript that can have properties and methods just like normal objects have properties and methods. You can even use the Function() constructor to create new function objects.

1. Properties

[length property]: The length property of the arguments object represents the number of actual parameters, while the length property of the function represents the number of formal parameters.

function add(x,y){
    console.log(arguments.length)//3
    console.log(add.length);//2
}
add(1,2,3);

[name attribute]: The function defines a non-standard name attribute, through which the name specified by the given function can be accessed, and the value of this attribute is always equal to the identifier following the function keyword, the name attribute of the anonymous function Is empty.

//IE11-浏览器无效,均输出undefined
//chrome在处理匿名函数的name属性时有问题,会显示函数表达式的名字
function fn(){};
console.log(fn.name);//'fn'
var fn = function(){};
console.log(fn.name);//'',在chrome浏览器中会显示'fn'
var fn = function abc(){};
console.log(fn.name);//'abc'

[Note]: The name attribute has long been widely supported by browsers, but it was only written into the standard until ES6.
ES6 has made some changes to the behavior of this property. If you assign an anonymous function to a variable, the ES5 name property will return an empty string. The ES6 name property returns the actual function name.

var func1 = function () {};
func1.name //ES5:  ""
func1.name //ES6: "func1"

If you assign a named function to a variable, both ES5 and ES6 name properties return the original name of the named function.

var bar = function baz() {};
bar.name //ES5: "baz"
bar.name //ES6: "baz"

The function instance returned by the Function constructor has the value of the name attribute "anonymous".

(new Function).name // "anonymous"

It can be seen that the function object generated by the constructor is an anonymous function.
For the function returned by bind, the name attribute value will be prefixed with "bound".

function foo() {};
foo.bind({}).name // "bound foo"
(function(){}).bind({}).name // "bound "

[prototype property]
Each function has a prototype property, which points to a reference to an object, which becomes a prototype object. Each function contains a different prototype object. When a function is used as a constructor, the newly created object inherits properties from the prototype object.

function fn(){};
var obj = new fn;
fn.prototype.a = 1;
console.log(obj.a);//1

method

[apply() and call()]
Each function contains two non-inherited methods: apply() and call(). The purpose of these two methods is to call a function in a specific scope. In fact, it is equivalent to pointing this in the function body to the newly passed in object.
To call a function f() as a method of object o, use call() and apply() like this.

f.call(o);
f.apply(o);

Assuming that there is no m method in o, it is equivalent to

o.m = f; //将f存储为o的临时方法
o.m(); //调用它,不传入参数
delete o.m; //将临时方法删除

a concrete example

window.color = "red";
var o = {color: "blue"};
function sayColor(){
    console.log(this.color);
}
sayColor();            //red
sayColor.call(this);   //red
sayColor.call(window); //red
sayColor.call(o);      //blue
//sayColor.call(o)等价于:
o.sayColor = sayColor;
o.sayColor();   //blue 这里其实是方法调用,所有函数中的this指向o这个对象。
delete o.sayColor;

The apply() method receives two parameters: one is the scope in which the function is run (it can be said to be the parent object of the function to be called, it is the calling context, and the reference to it is obtained through this in the function body), and the other is parameter array. Among them, the second parameter can be an instance of Array, or it can be an arguments object.

function sum(num1, num2){
    return num1 + num2;
}
//因为运行函数的作用域是全局作用域,所以this代表的是window对象
function callSum1(num1, num2){
    return sum.apply(this, arguments);
}
function callSum2(num1, num2){
    return sum.apply(this, [num1, num2]);
}
console.log(callSum1(10,10));//20
console.log(callSum2(10,10));//20

The call() method is the same as the apply() method, the only difference between them is the second parameter received. apply() takes an array, and call() takes a list of arguments.

function sum(num1, num2){
    return num1 + num2;
}
function callSum(num1, num2){
    return sum.call(this, num1, num2);
}
console.log(callSum(10,10));   //20

 As for whether to use apply() or call(), it all depends on which function is the most convenient way to pass parameters. If you plan to pass in the arguments object directly, or the containing function receives an array first, it is definitely more convenient to use apply(); otherwise, call() may be more appropriate.
 In non-strict mode, when using the function's call() or apply() methods, null or undefined values ​​are converted to global objects. In strict mode, the this value of a function is always the specified value.

var color = 'red';
function displayColor(){
    console.log(this.color);
}
displayColor.call(null);//red
var color = 'red';
function displayColor(){
    'use strict';
    console.log(this.color);
}
displayColor.call(null);//TypeError: Cannot read property 'color' of null

application

[1]: Call the native method of the object

var obj = {};
obj.hasOwnProperty('toString');// false
obj.hasOwnProperty = function (){
  return true;
};
obj.hasOwnProperty('toString');// true
Object.prototype.hasOwnProperty.call(obj, 'toString');// false

[2]: Find the largest element in the array

var a = [20,30,40,50,100];
Math.max.apply(null,a); //100

[3] Convert the array object to a real array.

Array.prototype.slice.apply({0:1,length:1});//[1]
//或者
[].prototype.slice.apply({0:1,length:1});//[1]

What is passed in is a pseudo-array.
[4]: Push the value of one array to another array

var a = [];
Array.prototype.push.apply(a,[1,2,3]);
console.log(a);//[1,2,3]
Array.prototype.push.apply(a,[2,3,4]);
console.log(a);//[1,2,3,2,3,4]

The underlying implementation principle

a.push = push; //把push方法存储为a的一个临时方法
a.push([1,2,3]); //调用它 
delete a.push; //将临时方法删除

Very simple if you use indefinite parameters in ES6

var a  = [...[1,2,3],...[2,3,4]];
console.log(a);//[1,2,3,2,3,4]

[5] Binding the object of the callback function
Because the apply method (or call method) not only binds the object where the function is executed, but also executes the function immediately, so the binding statement has to be written in a function body. A more concise way to write it is to use the bind method described below.

var o = {};
o.f = function () {
  console.log(this === o);
}
var f = function (){
  o.f.apply(o);
};
$('#button').on('click', f);

[toString()]: The toString() instance method of the function returns the string of the function code, while the static toString() method returns a string similar to '[native code]' as the function body.

function test(){
    alert(1);//test
}
test.toString();/*"function test(){
                    alert(1);//test
                  }"*/
Function.toString();//"function Function() { [native code] }"

[toLocateString()]: The toLocateString() method of the function returns the same result as the toString() method.

function test(){
    alert(1);//test
}
test.toLocaleString();/*"function test(){
                    alert(1);//test
                  }"*/
Function.toLocaleString();//"function Function() { [native code] }"

[valueOf()]: The valueOf() method of the function returns the function itself.

function test(){
    alert(1);//test
}
test.valueOf();/*function test(){
                    alert(1);//test
                  }*/
typeof test.valueOf();//'function'
Function.valueOf();//Function() { [native code] }

And the return value of this property is executable.

function test(){
       console.log(1);
   }
   test.valueOf()(); //1;

Reprinted from: Little Match's Blue Ideal
http://www.cnblogs.com/xiaohuochai/p/5613593.html
When reading the teacher's blog, I treat it as a book, so most of my blogs come from the teacher's blog The original words and examples, plus some of my own understanding, and made appropriate annotations, and some tests on the teacher's code.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325644812&siteId=291194637