js之作用域和面向对象

作用域

  1. JavaScript以函数为作用域
  2. 函数的作用域在函数未被调用之前,已经创建
  3. 函数的作用域存在作用域链,并且也是在被调用之前创建

示例一

    xo = "alex";
    
    function func(){
        // var xo = 'eric';
        function inner(){
            // var xo = 'tony';
            console.log(xo);
        }
        
        inner()
    }
    
    func()

结果

Alex

示例二

        xo = "alex";
        
        function func(){
            var xo = 'eric';
            function inner(){
                
                console.log(xo);
            }
            
            return inner;
        }
        
        var ret = func()
        ret()

结果

eric

示例三

        xo = "alex";
        
        function func(){
            var xo = 'eric';
            function inner(){
                
                console.log(xo);
            }
            var xo = 'tony';
            
            return inner;
        }
        
        var ret = func()
        ret()

结果

tony

因为词法分析结束之后AO链上只有AO={xo:eric},执行的时候

  1. xo = 'eric' 2. xo = 'tony' 再次ret()进行调用的时候就输出了tony

面向对象

        function foo(){
            var xo = 'alex';
        }
        
        foo()
        
        ================================
        
        function Foo(n){
            this.name = n;
            this.sayName = function(){
                console.log(this.name);
            }
        }
        
        var obj1 = new Foo('we');
        obj1.name
        obj1.sayName()
        
        
        var obj2 = new Foo('wee');
        obj2.name
        obj2.sayName()

每次新建一个实例都会在内存中创建方法sayName(),sayAddress().这无疑是低效的,解决的方法就是将这些可以共享的方法保存在原型对象中,从而让每个实例都继承这些属性或者方法.可有使用原型解决。

    原型:
    
        function Foo(n){
            this.name = n;
        }
        # Foo的原型
        Foo.prototype = {
            'sayName': function(){
                console.log(this.name)
            }
        }
        
    
        obj1 = new Foo('we');
        obj1.sayName()
        
        obj2 = new Foo('wee');

// 我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象;
// 用途:包含可以由特定类型的所有实例共享的属性和方法;
// 理解:prototype是通过调用构造函数创建的那个对象的原型对象;
// 使用原型的好处是可以让所有对象实例共享它所包含的属性和方法;
// 也就是说,不必在构造函数中定义对象信息(属性/方法),而是可以直接将这些信息添加到原型中;

构造函数、原型对象和实例对象关系图如下:

  • 因为最根上的object拥有一个prototype属性,而js中所有的对象又都继承自object,所以js中所有的对象都拥有一个prototype属性,而在js中函数也是对象,所以js中每个函数也都有一个prototype属性。

  • 而每一个prototype属性又会获得一个constructor属性

  • 该constructor属性有一个隐含的指针,指向了prototype属性所在的函数。

  • 当通过new Person() 创建一个对象实例后,该实例包含一个隐含的指针,指向了Person.prototype

原文地址:https://www.cnblogs.com/wspblog/p/6102256.html