JavaScript 函数、作用域 及 面向对象

函数

// 普通函数
function func(arg){  //arg 为形式参数
  console.log(arg)  
}

setInterval("func(123)",5000);  // 执行普通函数: 函数名(实参)

// 匿名函数
setInterval(function(){
  console.log(123)
},5000);

// 自执行函数: 创建函数, 当解释到它时函数内部自动执行,可避免函数名相同造成冲突

(function(arg){
  console.log(arg);
})('123')

相当于
function func(arg){ 
  console.log(arg)  
}
func('123')

 

作用域

在其他语言中以代码块{}作为作用域

如C#:

public void Func(){
  if (1==1){
    string name= 'Java';
  }
  console.writeline(name);
}
Func()  // 不能执行成功,name是创建的局部变量,只在if{}代码块中生效

在python中以函数为作用域

def func():
  if 1==1:
    name= 'Python'
  print(name)
func()  # 正常执行
def func():
  if 1==1:
    name= 'Python'
  print(name)
func()
print(name) # 报错

JavaScript 的作用域
1. 默认以函数为作用域 (let例外)

function func(){
  if (1==1){
    var name='JS';
  }
  console.log(name);
}

func()  // 结果打印JS

 

2. 函数的作用域在函数未被调用之前,已经创建

function func(){
  if (1==1){
    var name='JS';
  }
  console.log(name);
}

3. 函数的作用域存在作用域链,并且也在被调用之前创建

示例1:

xo='1'

function func(){
  var xo='2';

   function inner{
    var xo='3';
    console.log(xo);
  }
  inner()
}
func() // 结果打印3,注释var xo='3'则打印2,再注释 var xo='2'则报错

 示例2: 

xo='1'

function func(){
  var xo='2';

   function inner{
    console.log(xo);
  }
  return inner;
}
var ret = func()
ret() // 结果打印2,如果注释 var xo='2'则打印 1

示例3

xo='1'

function func(){
  var xo='2.1';

   function inner{
    console.log(xo);
  }
  var xo='2.2'; 
  return inner;
}

var ret = func()
ret() // 结果打印 2.2


4. 函数内局部变量提前声明(JS 特有)
示例1:

function func(){
  console.log(xo);
}

func(); // 直接报错

示例2:

function func(){
  console.log(xo);
  var xo='1';
}

func(); // 输出undefied,代码由上而下执行

相当于:

function func(){
  var xo; ## 解释器会自动找到函数内所有的变量提前声明
  console.log(xo);
  var xo='1';
}

func();

 

词法分析

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body> 
    <script>
        function t1(age){
            console.log(age); // 打印function age()
            var age = 27; 
            console.log(age); //  打印 27
            function age(){}; 
            console.log(age);  //  打印 27
        }

        t1(3);

        /*   浏览器解释器解释到函数时并未立即执行函数内部代码,而先进行词法分析,函数在调用前的一瞬间会形成一个活动对象 active object(AO) 
        1. 形式参数 (age)   
        2. 局部变量 var age = 27    
        3. 声明表达式 function age(){}

        1. 分析形式参数
            AO.age=undefied 
            AO.age=3; 覆盖 undefied 
        2. 分析局部变量 
            AO.age=undefied; ?
        3. 分析声明表达式
            AO.age=function ,声明表达式优先级最高
        */ 
    </script>
</body>
</html>

 

 

JavaScript 的面向对象(函数的变种)及 原型

function foo(n){
this.name= n;  // this 相当于python的self, 代指对象。当函数中有this关键字时,可以把这个函数看成类
}

var obj= new foo('a'); // 使用new关键字创建对象
obj.name 
function foo(n){
  this.name= n;
  this.sayName= function(){
    console.log(this.name)
  }
}

var obj1= new foo('a');
obj1.name
obj1.sayName()


var obj2= new foo('b');
obj2.name
obj2.sayName()

这样写不合理,在内存中重复地定义了sayName,浪费资源


改进:

function Foo(n) {   // 相当于构造函数
  this.name=n;
}

Foo.prototype= {  // 表示Foo的原型
  'sayName': function(){
      console.log(this.name)
    }
  }

var obj1= new foo('a'); 
obj1.sayName('a')   //去原型中找相应的函数
var obj2= new foo('b');
obj1.sayName('b')

 

Python的面向对象:

class Foo:
  def __init__(self, name):
    self.name=name

  def sayName(self):   # python中sayName在类中,在内存中只保存一份
    print(self.name)

obj1=Foo('a')
obj2=Foo('b')

 

posted @ 2017-10-29 17:53  bobo0609  Views(157)  Comments(0)    收藏  举报