我知道的JavaScript的Function对象

本文之所以单独拿函数来讲解,是因为JavaScript函数有其独特之处。

1. javascript函数默认没有重载

我们可以看到函数即使没有定义参数,调用时传递参数仍然可以传递参数,参数被argument对象接收

function sayHi() {
    console.log(arguments.length);
    if (arguments[0] == "bye") {
        return;
    }
    console.log("arguments[0]="+arguments[0]);
}

sayHi("hello");
console.log("sayHi instanceof Function="+(sayHi instanceof Function)); //true
console.log("sayHi instanceof Object="+(sayHi instanceof Object));  //true
//说明函数基类是Object
console.log("Function instanceof Object="+(Function instanceof Object));//true

2. 闭包: 词法表示包含不被计算的变量(变量不在函数内计算)的函数

2.1 这就是一个简单的闭包

var sMessage="hello world";
function sayHello() {
    console.log(sMessage);
}
sayHello(); // ''hello world''

2.2 在函数中定义一个闭包(也就是说函数中定义函数)

var iBaseNum=10;
//函数不return数据默认返回undefined
function addNum(iNum1,iNum2) {
    function doAdd() {
        return iNum1+iNum2+iBaseNum;
    }
    return doAdd;
}
console.log("addNum(10,10)="+addNum(10,10)());

3. ECMAScript不仅可以创建对像,修改已有对象的行为。

通过prototype属性,可以改变和添加构造函数的属性和方法,这点已经在原型继承那篇文章已经在使用

3.1 创建新方法

3.1.1 通过对象已有方法创建新方法

我们知道Number类型toString方法很容易讲数据转为各种进制,使用时传入进制,即可转换。

var num=new Number(10);
console.log(num.toString(16)); //10转为16进制a

我们换一种直观写法

Number.prototype.toHexString=function () {
    return this.toString(16)
}
console.log("num.toHexString()="+num.toHexString());

3.1.2 重命名已有方法,不改变原来方法效果

Array.prototype.enqueue=function (item) {
    this.push(item);
}

Array.prototype.dequeue=function () {
    this.shift();
}

var arr=new Array(3);
arr[0]="George";
arr[1]="John";
arr[2]="Thomas";
arr.enqueue("Bill");
console.log("arr="+arr);
arr.dequeue();
console.log("arr="+arr);

3.1.3 添加与已有方法无关的方法

// ES5开始提供了indexOf方法

Array.prototype.indexOf=function (item) {
    for(var i=0;i

3.1.4 为本地对象添加新方法

//要给每个本地对象都添加上新方法,必须定义在Object的prototype属性上。

Object.prototype.showValue=function () {
    console.log(this.valueOf());
};

var str="hello";
var iNum=25;

str.showValue();
iNum.showValue();

console.log(Object.prototype.constructor); //Object() { [native code] }
console.log(Object.constructor); // Function() { [native code] }
var num= new Number(10);
console.log(Number.prototype.constructor); // Number() { [native code] }
console.log(Object.constructor);   //Function() { [native code] }

3.2 重新定义已有方法

//函数名只是指向函数的指针,可轻松修改指针指向其它函数

function sayHi() {
    console.log("hi");
}
// Function 的 toString() 方法通常输出的是函数的源代码
console.log(sayHi.toString()); //function sayHi() {console.log("hi");}
//重新定义已有方法
Function.prototype.toString=function () {
    return "Function code hidden";
}
//改变后
console.log(sayHi.toString()); //Function code hidden

问题:toString指向的原始函数函数会被销毁,由于以后你可能还会用到。
所以最稳妥的做法是再覆盖原始方法之前报这个函数指针存起来

使用前用originalToString存储原始的toString指针(函数名就是指向函数的指针)

Function.prototype.originalToString=Function.prototype.toString;
// 新toString方法,函数判断函数源码长度是否大于100
Function.prototype.toString=function () {
    if(this.originalToString().length>100){
        return "Function too long to display.";
    }else {
        return this.originalToString();
    }
}

4. 极晚绑定(very late binding)(对象定义完后,才绑定方法和属性)

其实这点已经在前面文章讲到过,还是简单说一下

var obj=new Object();
Object.prototype.sayHi=function () {
    console.log("我是极晚绑定的sayHi")
}
Object.prototype.name="我是极晚绑定的属性";

obj.sayHi(); //我是极晚绑定的sayHi
console.log(obj.name); //我是极晚绑定的属性

对象在已经创建完毕后,再给对象绑定方法和属性能立即在前面已创建对象上使用

你可能感兴趣的:(我知道的JavaScript的Function对象)