Function函数所有的参数全都是字符串
函数即对象
Function对象的实例 -- 高级技巧 --- 写框架必须用的
第一种方法
function add1(a,b){ return a+b; }
第二种方法
//前面表示参数,后面表示函数语句
var add2 = new Function("a","b","return a+b");
arguments
重要性:9分 使用频率 8分 考试点:10分
function add(a,b,c,d){ alert(arguments.length); alert(arguments[0]); }
arguments只有在代码运行的时候才起作用
arguments是一个数组,保存函数的参数 -- 准确的说是伪数组
什么是形参 什么是实参
形参:函数定义的时候的参数
实参,用户调用函数的时候传递的参数
length指的是实际参数个数 arguments.length指的是实参个数
function checkVarCount(a, b) { if (checkVarCount.length == arguments.length) { alert("形参和实参个数一样"); }else{ alert("形参和实参的个数不一样"); } } checkVarCount(1, 2);//形参和实参个数一样 checkVarCount(1);//形参和实参的个数不一样
call
call的作用:
1.修改this指向。
2.借用别人的东西
3.伪数组-将dom元素集合数组话
4.判断数据类型
借用
student对象借用myclass对象中的getAllStudentsNumbers方法
//对象1 var myclass={ getAllStudentsNumbers:function(){ return 130} }; //对象2 var student={ getDetail:function(){ return {name:'莉莉',aihao:'唱歌跳舞'} } }; //借用 -- 供爷法则 console.log(myclass.getAllStudentsNumbers.call(student))
传参
1.对象
//对象1 var myclass={ getAllStudentsNumbers:function(sum,sum1){ return sum+sum1} }; //对象2 var student={ getDetail:function(){ return {name:'莉莉',aihao:'唱歌跳舞'} } }; //借用 -- 供爷法则 console.log(myclass.getAllStudentsNumbers.call(student,10,200)) console.log(myclass.getAllStudentsNumbers.apply(student,[10,200]))
2.函数其实也是对象
function add(a, b) { alert(a + b); } function sub(a, b) { alert(a - b); } /*借用:就是把人家的方法放到自己中来*/ add.call(sub, 3, 1);
什么叫伪数组:
伪数组:只有数组的部分功能:length。下标,无法访问数组对象中的方法。
这是一种固定用法:
Array.prototype.slice.call(arguments)
能将具有length属性的对象转成数组
js中常见的伪数组:通过document获取的dom集合,最为常用的arguments
这些伪数组无法使用Array对象中的方法,因为他们不是数组对象,就是普通的含有length属性的json对象而已
比如:var json = {1:'',2:'',length:2}
我们通过如下方式将其转换成数组
var divs = document.getElementsByTagName("div") /* slice : 截取数组,返回的还是数组,这里我们截取全部 */ var domNodes = Array.prototype.slice.call(divs);
这样domNodes就可以应用Array下的所有方法了。
var fackArray1 = {0:'first',1:'second',length:2}; Array.prototype.slice.call(fackArray1);// ["first", "second"]
apply
基础
妙用实例
1.如何获取一个数组的最大值
参数数组拆分法则:传递一个数组,其实会将其拆成很多个参数
适用场景:函数可以接受不限个数的参数。
这样我们只能使用arguments来管理可变参数,比如max min push join split replace
在js中有很多这样支持可变参数的函数
大家还记得我们前面写的extend,也是支持可变参数
巧用apply虽然传递的是数组,但是使用的时候是把数组拆开的。。等价于 return Math.max.call(null,1,2,3,4,5)。。所以等价于:Math.max(5,7,9,3,1,6)
function getMax2(arr){ return Math.max.apply(null,arr); /* return Math.max.call(null,1,2,3,4,5);*/ } console.log(getMax2([1,2,3,4,5,6,7]))
2.将一个数组的值合并到另一个数组-----使用apply写法
rray.prototype.push 可以实现两个数组合并
同样push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN),push(arr,2,3,3,3,3)
所以同样也可以通过apply来装换一下这个数组:
Array.prototype.push.apply(arr1,arr2);
apply实现继承
调用函数的五种方式
1. 普通模式
function func() { console.log("Hello World"); } func();
2.函数表达式
var func = function() { console.log("你好,传智播客"); }; func();
3.方法调用模式
函数调用模式很简单,是最基本的调用方式.
但是同样的是函数,将其赋值给一个对象的成员以后,就不一样了.
将函数赋值给对象的成员后,那么这个就不在称为函数,而应该叫做方法.
// 定义一个函数 var func = function() { alert("我是一个函数么?"); }; // 将其赋值给一个对象 var o = {}; o.fn = func; // 注意这里不要加圆括号 // 调用 o.fn();
4. 构造函数调用模式
// 同样是函数,在单纯的函数模式下,this表示window;
// 在对象方法模式下,this指的是当前对象.
// 除了这两种情况,JavaScript中函数还可以是构造器.
// 将函数作为构造器来使用的语法就是在函数调用前面加上一个new关键字. 如代码:
// 定义一个构造函数 var Person = function() { this.name = "传智播客"; this.sayHello = function() { alert("你好,这里是" + this.name); }; }; // 调用构造器,创建对象 var p = new Person(); // 使用对象 p.sayHello();
5.apply call调用模式
caller
返回函数调用者
caller的应用场景 主要用于察看函数本身被哪个函数调用
callee
返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文.
callee是arguments 的一个属性成员,它表示对函数对象本身的引用
arguments.callee.length可以获取实参参数
callee用处1 用来判断实际参数跟行参是否一致
// callee表示当前正在执行的函数对象,其实是函数的一个实例化 alert(arguments.callee.toString()); if (arguments.length == arguments.callee.length) { window.alert("验证形参和实参长度正确!"); return; } else { alert("实参长度:" + arguments.length); alert("形参长度: " + arguments.callee.length); } } //当函数被执行的时候,生成一个实例 calleeLengthDemo(1);
什么是递归
一个方法,自己调用自己,用上一次调用得出的结果作为这次的参数
callee用处2 调用自身 - 比如递归函数
优点:这样就让代码更加简练。又防止了全局变量的污染
var fn=(function(n){ if(n>0) return n+arguments.callee(n-1); return 0; })(10); alert('采用callee方式:'+fn)
constructor
js中原来没有对象的概念,通过函数来间接实现面向对象
我们将创建对象的时候那个函数称之为构造函数
我们可以通过constructor属性获取某个对象的构造函数
constructor 属性就是用来构造对象实例的函数引用
1.构造函数 创建的对象
function Student(name) { this.name = name; } var zhangsan = new Student('张三'); if (zhangsan.constructor == Student)
2.字符串对象
var str = new String("Hi"); if (str.constructor == String)
prototype
原型对象