js中的函数对象的理解1

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

什么是函数?


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

一般情况下,函数都具备参数和返回值




函数如何创建? 

常见的函数有哪些??

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   单击



ondblclick  双击



onfocus     获得焦点




onblur     失去焦点



onmouseover     鼠标划入



onmouseout     鼠标划出




onmousemove     鼠标移动



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

为什么会有栈和堆??

索引思维:




栈相当于堆的索引



栈和堆


什么是变量声明提升??

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的预编译期间就形成了,且不会再改变


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);
}


猜你喜欢

转载自blog.csdn.net/kangkang_hacker/article/details/80532371