• JavaScript面向对象及相关知识


    最近在学习JavaScript面向对象,写下自己的理解及相关资料,以备查阅。

    一.面向对象中涉及的相关几个概念 

    1.作用域

       所谓作用域,就是说属性和函数的可访问范围。在JavaScript中,作用域分为两种。全局作用域和局部作用域。

    所有没有var 声明 或 定义于最外层函数和最外层函数外面即为全局作用域。也就是定义可以随意调用。

    自定义函数内部用var声明的为局部作用域。

        var num = 1;                        //全局作用域
        window.onload = function() {        //最外层为全局作用域
            var   age = 18;
            function turn() {               //局部作用域,内部用var声明的只能被turn读取
                     sex = "男";            //未用var声明,为全局变量(可能只想用作局部,这样会出现bug,不推荐)
                var name = "刘某";          //局部变量
                function test() {
                    var data = "好";
                    var name = "王某";
                    console.log(name)       //王某
                };
                console.log(name)           //刘某
            }
        }

    需注意的是 读取属性(变量)时是先在最近的作用域中查找,没有就往上查找。最后查找全局,未定义则报错 undefined。

    2.闭包

    在JavaScript中,一个函数自带有作用域。一函数嵌套在另一函数内,内部函数可以访问到外部函数的属性,但外部函数和其他函数访问不到内部函数,为了解决这问题。闭包应运而生。

    闭包的定义就是函数内部与其他函数连接的桥梁(常用return指向)。

        function test(){
            var n = 2;              //定义为局部变量 外部函数不能访问            
            function f2(){
                console.log(n);
            }
            return f2;             //用return 返回  
        }
        var result=test();  
            result();              // 2 外部可以得到值

    3. this指向

        var name = "二货";                    //全局 指向window
    
        function fooCoder(x) {
            this.x = x;
        }
        fooCoder(2);                         //函数调用,this指向window
    
        var person = {
            name : "foocoder",
            hello : function(sth){
                console.log(this.name + " says " + sth);
            }
        };
        person.hello("hello world");          //对象调用时,this指向对象本身(Person)
    
        function Foo(name,color) {
            this.name=name;
            this.color=color;
        }
        var cc=new Foo("liuxing","yellow");  //调用构造函数时,this指向生成的实例(cc)
    
        var persone = {
            name : "foocoder",
            hello : function(sth){
                var that = this;
                var sayhello = function(sth) {
                    console.log(that.name + " says " + sth); //函数内部this指向window(一说为JavaScript设计有误)
                };
                sayhello(sth);
            }
        }
        person.hello("hello world");       //foocoder says hello world
    View Code

     总结如下(这是博客园某博主总结的,一时找不到该博客,感谢。)

      1.当函数作为对象的方法调用时,this指向该对象。

      2.当函数作为淡出函数调用时,this指向全局对象(严格模式时,为undefined)

      3.构造函数中的this指向新创建的对象

      4.嵌套函数中的this不会继承上层函数的this,如果需要,可以用一个变量保存上层函数的this。

    二.javascript OOP

     在javascript没有类的概念。实现继承功能的方法一般是利用原型(prototype)。今天先更到这。等理解稍透彻再来重写。

     // 声明 Animal 对象构造器
        function Animal() {}
        // 将 Animal 的 prototype 属性指向一个对象,
        // 亦可直接理解为指定 Animal 对象的原型
        Animal.prototype = {
            name: "animal",
            weight: 0,
            eat: function() {
                alert( "Animal is eating!" );
            }
        }
        // 声明 Mammal 对象构造器
        function Mammal() {
            this.name = "mammal";
        }
        // 指定 Mammal 对象的原型为一个 Animal 对象。
        // 实际上此处便是在创建 Mammal 对象和 Animal 对象之间的原型链
        Mammal.prototype = new Animal();
        // 声明 Horse 对象构造器
        function Horse( height, weight ) {
            this.name = "horse";
            this.height = height;
            this.weight = weight;
        }
        // 将 Horse 对象的原型指定为一个 Mamal 对象,继续构建 Horse 与 Mammal 之间的原型链
        Horse.prototype = new Mammal();
        // 重新指定 eat 方法 , 此方法将覆盖从 Animal 原型继承过来的 eat 方法
        Horse.prototype.eat = function() {
            alert( "Horse is eating grass!" );
        }
        // 验证并理解原型链
        var horse = new Horse( 100, 300 );
        console.log( horse.__proto__ );
        console.log( Horse.prototype.__proto__ === Mammal.prototype );
        console.log( Mammal.prototype.__proto__ === Animal.prototype );
        //对象的_proto_来实现对原型的隐式引用
        function Person(age){
            this.age=age;
        }
        var b=new Person("sss");
        //验证构造出来的函数_proto_属性是否指向构造器的prototype
        console.log(b.__proto__ === Person.prototype);
        //原型本身是一个Object对象,所以他的隐式引用指向了Object构造器的prototype属性
        console.log(Person.prototype.__proto__ === Object.prototype);
        //构造器Person本身是一个函数对象
        console.log(Person.__proto__ === Function.prototype)
        //原型链
        function Nperson(){}
        Nperson.prototype={
            name:"刘星星",
            age:"89",
            num: function () {
                console.log(1)
            }
        }
        //调用原型的属性为函数时 加上()
        Nperson.prototype.num();
        function Mperson(){}
        //将新构造器的原型指向已有的构造器 它原型是指向的函数 它隐式调用{原型的原型}为指向函数{对象}的几个属性 name age
        //创建了Mperson和Nperson的原型链
        Mperson.prototype = new Nperson();
        console.log(Mperson.prototype.__proto__);
        Mperson.prototype.num();
        //使用Horse对象构造器
        function Horse(height,width){
            this.name   = "liuxingxing";
            this.height = height;
            this.width  = width;
        }
        //将多个函数{函数的属性}链接起来 实现原型链{属性在几个函数里都可取到}
        Horse.prototype = new Mperson();
        console.log(Horse.prototype.num);
        //修改原属性 不会替换之前的属性
        Horse.prototype.num="asdasd";
        console.log(Horse.prototype.num);
        //验证下原型链
        var acc=new Horse(200,500);
        console.log(Horse.prototype.age);
        //acc.__proto__ 等同于 Horse.prototype
        console.log(acc.__proto__ === Horse.prototype);
        console.log(Horse.prototype.__proto__ === Mperson.prototype);
        console.log(Mperson.prototype.__proto__ === Nperson.prototype);
        document.write(Mperson.prototype.__proto__.name);
        // 闭包 实现信息隐藏
        function User(pwd) {
            //定义私有属性
            var password = pwd;
            function getPassword() {
                // 返回了闭包中的 password
                return password;
            }
    
            //特权函数声明,用于该对象其他公有方法能通关特定方向访问到私有成员
            this.passwordSer = function () {
                return getPassword()
            }
        }
        //公有成员声明
        User.prototype.accd= function (pwd) {
            return this.passwordSer() === pwd;
        }
        //验证隐藏性
        var u = new User("liuxingxing");
        //公有的可以访问到
        console.log(u.accd("liuxingxing"));
        //私有的属性不能访问到
        console.log(u.password)
    View Code
  • 相关阅读:
    [转载]Axis2 and CXF的比较
    [转载]Axure RP 7.0下载地址及安装说明
    Eclipse配置总结
    201505大事记
    Gmail收不到邮件咋办?
    Mybatis-There is no getter for property named 'id' in 'class java.lang.String'
    EXTjs+SpringMVC+Mybatis实现照片的上传,下载,查看关键技术整理
    Ext如何Gird中如何显示时间类型的列?
    glibc
    圆形头像CircleImageView和Cardview使用
  • 原文地址:https://www.cnblogs.com/xiaoye1990/p/5348443.html
Copyright © 2020-2023  润新知