今日学习内容总结如下:
调用函数的4种方法
方法
1
:作为一个函数调用,基础语法【函数名
(
实参列表
)
】。函数实际上作为全局对象调用,会使
this的值成为全局对象,使用
window
对象作为一个变量,容易造成程序崩溃
<script>
function bb(){
this.name="zhangsan";//实际上是将name定义为全局属性
console.log(this); //输出的应该是window对象
}
bb();
window.bb();
document.writeln("window.name="+window.name); //证明name称为全局属性
document.writeln("name="+name);//实际输出和window.name一致
</script>
方法
2
:函数作为方法调用。函数作为对象的方法进行调用,会是
this
的值称为对象本身
//使用JSON格式定义对象,JSON的语法格式为{key1:value1,key2:value2...}
var p1={
"username":"zhangsan", //定义属性,格式为【属性名:值】
"age":18,
show:function(k){//定义方法,格式为【方法名称:function(形参){}】
console.log(this);
document.writeln(k+"---"+this.username+"---"+this.age);
}
};
//通过对象名.方法名的形式调用show函数
p1.show(12);
方法
3
:使用构造器的方式调用函数,构造函数中的
this
指向当前对象
function Person(){
this.name="zhangsan";//定义public属性
this.age;
this.show=function(){
console.log(this);
document.writeln("name:"+this.name+",age:"+this.age);
}
}
var p1=new Person(); //则function Person()会自动调用执行
alert(p1.name);//获取p1对象中的name属性值
alert(window.name);//不能获取到数据,因为Person中的this用于指代Person类型对象,不是
window对象
p1.show();//调用成员方法
方法
4
:作为函数间接调用。实现有
3
种不同方式
类和对象
定义函数后实际上可以得到
4
项内容
- 函数。可以直接调用
- 对象。Function类型的实例
- 方法。函数会自动附加到某个对象
- 类。函数是类的唯一构造器
//前面已经进行了试验
function Person(name,age){
this.name=name; //实例属性,每个实例都不一样,可以通过【对象名.属性名】的方式进行
访问
Person.nation="汉族"; //静态类属性,所有对象共享的属性,只能通过【类型名.属性名】
的方式访问
Person.show = function () { //静态类成员方法
console.log(this); //this可以使用,用于指代当前函数
console.log(this.username); //undefined
console.log(this.nation); //汉族
}
var bb=100; //局部变量或者理解为私有属性,不能通过对象名的方式进行访问,可以使用闭
包函数访问
var ff=function(){
return bb;
}
return ff;
}
class关键字
ES6
引入了
class
关键字可以用于定义类,但是需要考虑浏览器的支持问题
class Person{
constructor(){ //定义构造器函数,只能定义一个,名称固定,参数个数没有限制。如果需
要定义多个构造器可以考虑使用arguments判断参数格式
if(arguments.length>1){
this.username=arguments[0];// this用于定义公共属性
this.age=arguments[1];
} else if(arguments.length==1){
this.username=arguments[0];
this.age=99;
} else {
this.username="zhangsan";
this.age=18;
}
}
//可以定义成员方法,规则是【方法名称(参数列表){}】
show(){
return "Hello "+this.username+",今年"+this.age+"岁了!";
}
}
var p=new Person();
document.writeln(p.show());
p=new Person("lisi",55,true); //按照处理逻辑并没有接收arguments[2],所以true没有
使用
document.writeln(p.show());
函数间接调用的3种方式
直接调用
p.pp(1,2,3);
call方法动态调用函数
var ee=function(arr,fn){ //其中参数fn就是调用时才设置的函数
for(var index in arr){
fn.call(null,index,arr[index]); //调用函数fn,参数1调用的函数所属于的对象,
如果值为null则表示window,后面参数则是调用函数时的参数
}
}
//调用ee函数
ee([2,3,4,5,6],function(index,ele){ //function()就是传递给fn的函数
document.writeln("第"+index+"个元素是"+ele+"<br/>");
});
apply动态调用函数
通过
call
调用函数时必须在括号种详细列出每个参数,但是通过
apply
动态调用函数时,可以在括号中以arguments
代表所有参数
var ff=function(a,b){
alert(a+b);
}
ff.call(window,12,23); //12和23对应的就是函数中的参数,通过call方法动态调用时需要为每
个调用方法逐个的传入参数,写法为12,23
ff.apply(window,[12,23,34,56]);//通过apply方法动态调用方法时,能与arguments一次性传
入多个参数,例如这里的参数就是一个数组[12,23,34,56]
函数的参数处理
JavaScript
采用值传递方式,当通过实参调用函数时,传入函数里的不是实参本身,而是实参的不笨,因为在函数中修改参数值并不会对实参有任何影响。复合类型参数的是一个引用
<meta charset="UTF-8">
<script>
function ff(person) {
if (typeof (person) == 'object') {
person.age = 100;
} else alert('参数类型不是复合类型' + typeof person);
}
person={"age":99,toString:function(){return "age:"+this.age}};
ff(person);
document.writeln(person);
</script>
参数的新问题
在
JavaScript
中没有函数重载的概念,函数名称是函数的唯一标识,如果定义两个同名函数,则后盖前
function ff(person){
if(typeof(person)=='object'){
person.age=100;
} else
alert('参数类型不是复合类型'+typeof person);
}
ff(); //person形参对应的实参为undefined
原型
JavaScript
是基于原型的语言,原型可以理解为原件,通过精确地复制原件可以创建对象。
JavaScript
对象都有一个叫做原型的公共属性,这个原型属性就是构造函数的原型对象
prototype
。
function Person(){
this.name="Nicholas";
this.age=29;
this.job="Software Engineer";
this.sayName=function(){}
}