js中的函数对象的理解1

出自:https://blog.csdn.net/flqbestboy/article/details/77016829

什么是函数?


编程的角度:   具有某种功能的代码判断。
生活的角度:   函数就是一个完成特定功能的工具

一般情况下,函数都具备参数和返回值
js中的函数对象的理解1

js中的函数对象的理解1js中的函数对象的理解1js中的函数对象的理解1


函数如何创建? 

常见的函数有哪些??

JavaScript 全局对象:http://www.w3school.com.cn/jsref/jsref_obj_global.asp



Math.pow(a, 5);
Math.random()     [0,1)
alert("ok");
document.write("你好")


函数的定义方式:
function test(){
}

函数的好处有哪些?

1)  代码复用
2)  封装(隐藏细节)
3)  控制代码的执行时机

1  声明式

function test(){
     //声明会被提前,可以在任何地方调用
}

2  赋值式 

var test = function(){
     //只能在该函数以下位置,调用
//建议使用这种方式,会使程序更具逻辑性、可读性
}

两种创建方式的区别??

JS是一个脚本语言,那么它的代码,需要编译吗?   需要

在编译的过程中,所有的声明语句,都会被提前。

b();  //当执行函数b的时候,由于声明被提前,可以执行
a();  //当执行函数a的时候,由于a仍未定义,不可执行
function b(){
     document.write("aa");
}
var a=function(){
     document.write("123");
}
以上代码相当于:
var a;
function b(){
document.write("aa");
}
b();
a();
a=function(){
document.write("123");
}

如何执行函数?

函数与事件的结合?

onclick   单击
js中的函数对象的理解1js中的函数对象的理解1



ondblclick  双击
js中的函数对象的理解1



onfocus     获得焦点
js中的函数对象的理解1



onblur     失去焦点
js中的函数对象的理解1



onmouseover     鼠标划入
js中的函数对象的理解1


onmouseout     鼠标划出
js中的函数对象的理解1



onmousemove     鼠标移动
js中的函数对象的理解1


onload     页面加载完成

onkeydown     键盘被按下

onkeyup     键盘被松开

onkeypress     键盘按下并松开

onsubmit     表单提交事件

onmouseenter     鼠标划入(不支持冒泡)(区别于onmouseover支持冒泡)http://blog.csdn.net/u012076852/article/details/52045053
onmouseleave     鼠标划出(区别于onmouseout)

什么是匿名函数??

function(){
     //由于没名字,该函数无法调用
}

匿名函数如何运行??

(function(){
     //函数在定义的同时,立即执行。  也叫作函数的自运行。
})();
(function(){
     //函数在定义的同时,立即执行。  也叫作函数的自运行。
}());


函数的参数及返回值是什么?

参数不做类型检查

作用域


var a = 99;

function test(){
     var a = 10;
     alert(a); //10
}

test();

作用域链

var a = 100;
function m1(){
         var a = 200;
         function m2(){
                 console.log(a); //200
         }
         m2();
         console.log(a); //200
}
m1();
console.log(a); //100

为什么会有栈和堆??

索引思维:
js中的函数对象的理解1

js中的函数对象的理解1

栈相当于堆的索引


js中的函数对象的理解1

栈和堆

js中的函数对象的理解1js中的函数对象的理解1

什么是变量声明提升??

var n = 2;
(function(){
         console.log(n);  //undefined   2   
         var n = 10;
         console.log(n);  //10
})()
//以上写法   等价于   以下写法:
var n = 2;
(function(){
         var n; //变量的声明不管写在哪里,都会被提升到该作用域的最前面
         console.log(n); //这里应该是undefined
         n = 10; //这里只是一个赋值动作
         console.log(n);  //毫无疑问等于10
})()

变量和函数重名的问题??

var a = 10;
function a(){}
alert(typeof a);
//以上写法   等价于   以下写法:
var a;
function a(){}
a = 10;
因此a最终被10覆盖,则为number类型

arguments是什么?   该对象包含了函数执行时,传入的所有参数

function add(){
        //console.log(arguments instanceof Array); //确认是不是数组类型
        //console.log(arguments);
        var sum = 0;
        for(var i=0; i<arguments.length; i++){
                sum += arguments[i];
        }
        return sum;
}
console.log( add(10,222,32,46,5,6, 11,10,35) );
//arguments本身不是数组,而是经过封装的一个对象,它包含一个数组,即我们的参数列表
//由于它可以当成数组来使用for循环遍历,因此,我们管这类对象,叫做伪数组

arguments.callee是什么?
代表了函数本身
(function(num){
         if(num == 0) return 1;
         return num * arguments.callee(num-1);
})(5);


问题解析:  (有名字的匿名函数)

var a = function b(){
     b = 3;
     console.log(b);
}
a();

    //function b 看做一个有名字的 匿名函数
    //一个有名字的匿名函数,其函数名  是只读的,不可更改
    //同时,该函数名只能在函数内部使用,相当于局部变量
    //b(); 报错,无法调用,找不到b函数


JSON字面量对象和new 对象 的使用方式有什么区别?

//使用new关键字创建对象
var cat = new Object();

//使用json形式创建对象
var cat = {
        color : "black",
        age : 3,
        weight : "8kg"
}

打印一个对象不存在的属性?

var obj = {
     attr1 : "10",
     attr2 : 20,
     attr3 : 30
}
console.log(obj.attr4); //undefined

如何判断对象是否存在某个属性??

if(obj.attr){ 
     //对于attr等于0或null, 条件不成立
}

if("attr" in obj){
     //判断attr是否存在于对象obj当中
}

问题解析:

console.log(window.a);    //undefined
if (!("a" in window)) {    //不成立
    var a = 1;      //变量声明提升
}
alert(a);     //undefined

相当于 
var a;
if (!("a" in window)) {  
     a = 1;      
}




var a = 1,
    b = function a(x) { //有名字的匿名函数,此时a仅时局部变量,只能在函数内部使用
        x && a(--x);
    };
alert(a);     //1    a不是一个函数



function a(x) {
    return x * 2;
}
var a;       //变量声明提升
alert(a);     //function a(x)



function b(x, y, a) {
    arguments[2] = 10;
    alert(a);
}
b(1, 2, 3);  //正常情况下同步 10   严格模式"use strict"下不同步 3


闭包
可以访问外部变量的函数
function m1(){
     var x = 1;
     return function(){
          console.log(++x);
     }
}

m1()();  //2
m1()();  //2
m1()();  //2

var m2 = m1();
m2();  //2
m2();  //3
m2();  //4

作用域链,(作用域对象)在js的预编译期间就形成了,且不会再改变
js中的函数对象的理解1js中的函数对象的理解1


GC 垃圾回收机制: 自动回收



关于值传递    (函数内部的更改不影响外部)

var num = 50;
function add(num){
     num=100;
}
add(num);
console.log(num);

引用(指针 | 快捷方式)传递         (函数内部的更改会影响外部

var arr = [10,20,30];
function add2(arr){
     arr[0]=99;
}
add2(arr);
console.log(arr);

数据结构: 队列和链表


函数递归 :  当一个函数调用了函数自身,就会形成递归

1 阶乘  100!

100! = 100 * 99 * 98 * 97 * 96 ......
100! = 100 * 99!
             99! = 99 * 98!
                        98! = 98 * 97!
n! = n * (n-1)!
f(x) = x * f(x-1)

function f(x) {
     return x * f(x-1);
}

2 求和   1+2+3+4+5.........+n

function sum(n){
     if(n == 1) return 1;
     return n + sum(n-1);
}

3 最大公约数


function divisor(x,y){   //辗转相除法
     var r = x%y; 
     x = y;
     y = r;
     if(r==0) { 
          return x;
     } else {
          return divisor(x,y);
     }
}


function divisor(x,y){   //更相减损法
     if(x%2==0 && y%2==0){
          return 2*divisor(x/2,y/2); 
     } else {
          var max = Math.max(x,y);
          var min = Math.min(x,y); 
          var cha = max - min;
          if(cha == min) {
              return min; 
          } else {
              return divisor(cha, min);
          }
     }
}


4 斐波那契数列

//1  1  2  3   5  8  13  21  34  55  89 .........
//f(x) = f(x-1) + f(x-2);

function f(x) {
    if(x <= 2) {
        return 1;
    }
    return f(x-1) + f(x-2);
}