JavaScript_02_深入对象

深入对象

函数深入理解

函数的定义方式

函数是一个非常特殊的对象,也是Function类的一个实例;内存中存储的操作是通过一个键值对来存储;有三种定义方式如下:

//第一种定义方式
function fn1() {
    alert("fn1");
}
alert(typeof fn1);// function 也是一种数据类型

//第二种创建方式
var fn2 = function() {
    alert("fn2");
}
//第三种创建方式
var fn2 = new Function('num1','num2',"alert('fn3:'+num1+num2)");
fn2(11,12); //23

函数和对象的区别

虽然函数也是一个对象,但是和对象有一些区别:

  • 对象是通过引用指向对象来完成赋值
function fn1() {
    alert("fn1");
}
var fn2 = fn1;
fn1 = function() {
    alert("fnn1");
}
fn2();//fn1
fn1();//fnn1

在这里插入图片描述

  • 函数是通过对象的拷贝来完成赋值
var o1 = new Object();
var o2 = o1;
o2.name = "c10";
alert(o1.name);

在这里插入图片描述

函数的重载

JavaScript中没有函数重载,函数会在堆中复制原来的函数并指向新的内存地址,两个函数的内存地址不相同,而变量是指向后面复制的函数的,原来的函数没有对象指向。

function sum(num1,num2) {
    return num1+num2;
}
function  sum(num1) {
    return num1+100;
}

//一下两个值都为119
alert(sum(19));
alert(sum(19,20));

在这里插入图片描述

函数的值传递

函数作为参数传递

由于函数是function对象,可以直接把对象作为参数传递。

function callFun(fun,arg){
    return fun(arg);
}
 var say = function(str) {
    alert(str+":hello");
}
say(yjl);
callFun(say,yjl)

在这里插入图片描述

函数作为返回值传递

function fn1(arg) {
    var rel = funciton(num) {
        return arg+num;
    }
    return rel;
}
var f = fn1(20);
alert(f);
alert(f(140));

在这里插入图片描述

数组sort()方法分析

sort()默认只能对字符串进行排序操作,如果对数字或者字符串数字进行操作,需要提供比较函数,比较函数应该具有两个参数a和b,其返回值如下:

array.sort(sortby);//sortby 必须是函数
  • a > b return 1;
  • a == b return 0;
  • a < b return -1;
var p1 = new Person("Jhon",23);
var p2 = new Person("Leno",29);
var p3 = new Person("Ada",41);
var ps = [p1,p2,p3];
//年龄排序
function sortByAge(a,b) {
    return a-b;
    // 如果是字符串数字  [‘1’,‘2’,‘3’,‘4’];
    // return parseInt(a-b);
}
//姓名排序
funciton sortByName(a,b) {
    if(a.name>b.name) return 1;
    else if(a.name == b.name) return 0;
    else return -1;
}
//函数作为参数传递
ps.sort(sortByAge);
ps.sort(sortByname);

以上方法可以实现不同的排序,但是还不够灵活,希望通过使用一个函数更具传入的参数,就能按照参数的类型进行排序,如果传入年龄,自动按照年龄进行排序。

//函数作为返回值
function sortByProperty(propertyName) {
    var sortFun = function(obj1,obj2) {
        if(obj1[propertyName]>obj2[propertyName]) return 1;
        else if(obj1[propertyName]=obj2[propertyName]) return 0;
        else return -1;
    }
}
ps.sort(sortByProperty('name'));
ps.sort(sortByProperty("age"));

补充:属性的调用有两种方式

  • 对象.属性
  • 对象[属性]
 function Person(name,age) {
     this.name = name;
     this.age = age;
     this.address = "云南";
     //方法的创建
     this.say  = function() {
         alert(this.name+":哈哈哈")
     }
 }
for(var i in p1) {
    //可以获取对象显示声明的对象
    //alert(i); // 输出所有属性
    //获取对象属性和值  如果使用p1.i 回去找person中属性i,都没有定义,返回值为undefine
    alert(i+":"+p1[i]);
}

同理如果上面使用obj1.propertyName方式来获取属性,回去Person对象中找propertyName属性,我们并未设置,结果肯定为undefined

函数的内部属性

  • arguments.callee()

arguments对象用来可以获取相应的参数值,是一个数组;它的callee()方法可以反向调用。

function factorial(num) {
    if(num===1) {
        return 1;
    }
    // 函数的解耦合
    // return num*factorial(num-1);
    return num*arguments.callee(num-1);
}
var cf = factorial;
//不会报错
alert(cf(5));
factorial = null;
// 此时由于cf这个函数内部仍然调用factorial() ,factorial已经指向空了。
// 如上情况只能使用arguments.callee(arg),函数名已更改,内部的函数名也随之改动
alert(cf(5));

如果函数使用递归地情况下,外部名函数改变,就会报错,如用argumenta.callee()反调用外部函数,就能保持函数内外一致。

  • this

指向当前对象,可以用来设置当前对象的属性或者方法;特别注意this会更具对象调用的不同,所指向的对象也不同。

var color = "red";
function showColor() {
    alert(this.color);
}
function Circle(color) {
    this.color = color;
    this.showColor = showColor;
}
var c = new Circle("yellow");
// 使用c调用showColor();
c.showColor();
// 直接掉用showColor函数
showColor();

函数的常用属性和方法

  • length

    查看函数中参数的个数。

function fn1() {

}
function fn2(num1,num2) {

}
function fn3(num1) {

}
alert(fn1.length); //0
alert(fn2.length); //2
alert(fn3.length); //1
  • call(调用上下文,参数数组)
var color = "red";
function showColor() {
    alert(this.color);
}
function Circle(color) {
    this.color = color;
    //this.showColor = showColor;
}
var c = new Circle("yellow");
showColor.call(this);// 使用上下文调用,this指向windows对象,red
showColor.call(c); //yellow

/*
        *通过以上发现,使用call和apply之后,对象可以不需要定义方法
        * 通过apply或者call来调用对象
        * */
  • apply(调动上下文,参数1,参数2)
function sum(num1,num2) {
    return num1+num2;
}
function callSum1(num1,num2) {
    // 使用sum这个函数来完成一次调用,调用的参数就是callSum1这个函数的参数
    //apply 表示一组参数数组
    return sum.apply(this,arguments);
}
function callSum2(num1,num2) {
    return sum.apply(this,[num1,num2])

}
function callSum3(num1,num2) {
    //call是通过参数列表来完成传递,其他和apply没有任何区别
    return sum.call(this,num1,num2);
}
alert(callSum1(12,22));
alert(callSum2(33,22));
alert(callSum3(1,2));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值