js面向对象精要 第二章(持续更新)

 万物皆对象

 一 什么是函数
 1 函数就是可以执行的代码块 
   这个比较好理解 就是在一个大括弧里定义一段代码,封装了一系列逻辑操作,
   然后输入参数 调用函数(代码块) 返回处理结果 函数都是这么一个结果。


 2 函数可以通过函数声明和表达式两种定义方式
   这两种函数表示方法看起来差不多 但是是有一点差别的,函数声明会被提升到是上下文的顶部,上下文是什么东西:要么是       该函数被声明是所处的函数的范围,要么是全局范围的  这是可见性的问题后面的的文章可能会详细介绍
   
function myfunction (arg) {
return arg+'函数声明';
}
var  myfunction = function(arg) {
return arg+'函数表达式';

}

例子:
function myfunction (arg) {
console.log(arg+'函数声明') ;
}

var myfunction2=myfunction;
myfunction2('test')
function myfunction (arg) {
console.log(arg+'函数声明2') ;
}

myfunction2('test')

 你觉得两次运行下面的函数会有什么结果
 myfunction2('test')   

结果:

test函数声明2   

解释:这看出来js引擎对函数声明并不是一边运行,一边解析的 而是同意将函数声明的函数提升到上下文的顶部(相当于在先在顶部定义了myfunction函数 但由于我定义两次 所以后者把前者覆盖了。)至于为什么重新定义myfunction函数会影响到myfunction2呢 ,因为myfunction2=myfunction这句话只是将myfunction函数的引用赋值而已 ,myfunction2这个引用最后也是指向的值还是myfunction函数,所以myfunction函数改变 ,myfunction2指向的内容自然改变。

test函数声明2

解释:这个不用解释


3 函数就是一个值

   这就是一个js区别于其他语言的一个很有意思的一个特性 
   首先我们知道函数也是一个对象,你可以像使用对象一样使用函数,
   可以把函数当成变量赋值, 甚至可以把其当成参数传递给别的函数或许作为函数的返回值 基本上可以使用引用值的地方都      可以使用函数,
   这意味着函数威力无穷 灵活多变 但是 我们了解函数即对象之后 它的很多特性就很容易解释得通。
 二 怎么调用函数

 1 仅仅作为函数调用(待会解释)

   当我们通过表达式后声名定义函数后调用 例子:

     function  a(){};   a();   //作为函数调用

 2 作为对象的属性调用

   定义一个对象,函数作为其中的属性值,则是对象属性调用   例子:

    var obj={

 myfunc:function(){}

     }

obj.myfunc();

 3 call apply方法调用

  call方法和apply方法其实差不多,都是改变函数内部this值的一种手段,只是用的时候,需要的参数不一样而已。

三  函数调用js引擎做的工作

 当一个函数被调用的时候,js引擎其实不止只是为函数准备了好参数以供函数体调用,还有就是准备了arguments,this这两个默认参数,所以

function myfunc(){
   console.log(this)
   console.log(arguments)
}     //打印出两个对象

 调用函数的时候我们没有传这两个this arguments 参数 ,但是却能打印出来,这是因为这是js引擎默认传递的。问题来了,默认传递的这俩有啥用?

arguments:  js的独特之处在于你可以给函数传递任意数量的参数却不造成错误  例子:

定义

function myfunc(a,b,c){
   console.log(a)
   console.log(b)
   console.log(c)
}
调用
myfunc();   输出 undefined  undefined  undefined
myfunc('fd')   输出  fd   undefined  undefined
myfunc(3,5,5,2)  3 5 5

以上的调用都不会出错 无论你调用时传递的参数的实际数量少于或多余声名时的数量。 

从上面看出 当实际传递的参数少于形式参数时,没有接受的实际参数的参数会被自动赋予undefined,当实际传递的参数多于形式参数时,多余的参数会被遗弃,js引擎不会进行处理。所以引擎是怎么做到的?

其实就是靠着 arguments参数的作用 ,arguments是一个类似数组的一个对象。但那不是数组 ,虽然可以像数组通过过下标寻找成员,也有length属性,但真的不是数组;通过Array.isArray(arguments)永远返回false。

arguments对象以键值对的对象方式保留着实际参数  类似于

{ '0': arg,     注意是实际参数
  '1': arg2
}

所以我们可以通过arguments[index]来获取参数  arguments.length获取实际参数的个数。

所以  

function  test(){

return arguments[0];

}

console.log(test.length)  //打印形参个数  返回0

console.log(test(5))     //  打印实参          返回5   所以实际传递参数是不会对函数调用产生任何问题,所以有人问,如果arguments可以直接访问实际参数, 那为什么还要这些命名参数(定义函数是写下的参数名字) 答案很简单---因为方便呐,你想想每次你写函数体的时候都要arguments[0]来访问参数吗?而且有参数名字好记!

this:this是一个对象 每个函数作用域内都有一个this对象代表调用该函数的对象。在全局作用中,this表示全局变量。当一个函数被调用,默认this的值等于那个对象;

所以默认情况下引擎传递的this是默认的;但是我们可以通过call或apply改变默认this,强制制定this的值  例子

var obj={
   name:'djfk',
   callname:myfunc
}  
function myfunc(a){
   console.log(this)
   console.log(a)
}

myfunc.call(obj,'dfd')强制制定myfunc函数调用时的this的值为obj
输出
 { name: 'djfk', callname: [Function: myfunc] }
 dfd
未完  待续。。。。。。






  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值