2017-03-21 JS面向对象笔记

基本的面向对象

  • 拥有自己的属性
  • 拥有自己的方法
  • 数值,字符,布尔,对象, undefined
  • 数组, array

基本面向对象的写法

var dog = {
        name:'小花',
        age:1,
        friendDogs:['小黄','小虎'],
        eat:function(someThing){
        console.log('吃' + someThing);
        },
        run:function(someWhere){
        console.log('跑' + someWhere);
        }
}
dog.eat('奶');
dog.run('树下');

面向对象的常用写法

function dog(){
        var obj = new Object();
        obj.name = '未定义';
        obj.age = 0;    
        obj.eat = function(someThing){
         console.log(this.name + '吃' + someThing)
        };
        obj.run = function(someWhere){
        console.log(this.name + '跑' + someWhere);
        }
        run obj;
}
var smallDog = dog();
smallDog.name = '小花';
smallDog.age  = 1;
smallDog.eat('奶');
var bigDog = dog();
bigDog.name = '大花';
bigDog.age = 1;
bigDog.run('棠下');
bigDog.eat('肉');

this 对象的认识

  • this : this 所在的函数(方法)属于哪个对象,那么 this 就表示哪个对象
  • this 在事件指令中表示事件源
  • window.所有的全局变量都是它的属性,所有的全局的函数都是它的方法
  • this 在定时器表示 window
  • 任何一个函数都可以通过 New+ 函数调用创建一个对应的对象
  • 如果遇到 new 函数调用会创建一个新的对象,那么这个函数就属于新创建的对象,所以 this 表示这个对象

通过构造函数创建对象

  • 构造函数
    形式:第一个字母都是大写
    new: 可以创建一个对象返回来
创建对象,使用构造函数
function Dog(name,age,dogFriends){
        this.name = name;
        this.age = age;
        this.dogFriends = dogFriends;
        this.eat = function(someThing){
                  console.log(this.name + '吃' + someThing);
        }
        this.run = function(someWhere){
                  console.log(this.name +  '跑' + someWhere);
        }
}
//通过构造函数创建对象
var smallDog = new Dog('小花',1,['小虎','小明']);
smallDog.eat('奶');
smallDog.run('教室');

var bigDog = new Dog('大花',1,['大虎','大明']);
bigDog.eat('肉');
bigDog.run('树下');

通过构造函数创建对象优化


    //创建对象,使用构造函数
    //优化:就是使用json把参数保存起来,直接传递json
    function Dog(option) {
        var option = option ||{};

        this.name = option.name;
        this.age = option.age;
        this.dogFridends = option.dogFridends;
        this.eat = function (someThing) {

            console.log(this.name +'吃' + someThing);
        }
        this.run = function (someWhere) {
            console.log(this.name +'跑'+someWhere);
        }



    }

    //2.通过构造函数创建对象
    var smallDog = new Dog({name:'小花',age:1,dogFriends:['小虎','小明']});
    console.log(smallDog.name);
    console.log(smallDog.age);
    smallDog.eat('奶');
    smallDog.run('教室');

    var bigDog = new Dog({name:'大花',age:8,dogFriends:['大虎','大明']});
    console.log(bigDog.name);
    console.log(bigDog.age);
    bigDog.eat('肉');
    bigDog.run('棠下');

  • 当我们使用不同的对象调用函数的时候,这个函数不是同一个函数
  • 每次创建对象,调用函数的时候,这个函数都需要重新创建
  • 但是这两个函数功能是一样的,我们每必要每次创建一个对象都使用新的函数
  • 所以我们需要这个 eat 函数可以共用,无论哪个对象调用,都是同一个函数

原型属性的使用

  • 原型属性:可以扩展属性和方法,就是一个构造函数的共享库,以后所有创建的新的对象,都可以使用这个共享库中的方法以及属性
  • 优点是降低了创建方法的成本
Array.prototype.eat = function(){
        console.log('数组会吃东西');
};
Array.prototype.run = function(){
        console.log('数组会跑');
};

//原型库的第二种写法
Dog.prototype = {
        eat:function(someThing){
                  console.log(this.name + 
'吃' +someThing);
        },
        run:function(someWhere){
                  console.log(this.name + '跑' +someWhere);
        }
};

通过构造函数创建对象最终版

  • 要把属性也放在原型库中,使用一个初始化方法 _init
  • 在构造函数中调用初始化方法,然后把这个初始化方法放在原型库中,初始化方法用来初始化属性
function Dog(option){
        this._init(option);
}
Dog.prototype = {
        _init:funtion(option){
                var option = option || {};
                this.name = option.name;
                this.age = option.age;
                this.dogFriends = option.dogFriends;
          },
          eat:funtion(someThing){
                  console.log(this.name + '吃' + someThing);
          }
}
ar smallDog = new Dog({name:'小花',age:1,dogFriends:['小虎','小明']});
    console.log(smallDog.name);
    console.log(smallDog.age);
    smallDog.eat('奶');
    smallDog.run('教室');

    var bigDog = new Dog({name:'大花',age:8,dogFriends:['大虎','大明']});
    console.log(bigDog.name);
    console.log(bigDog.age);
    bigDog.eat('肉');
    bigDog.run('棠下');

面向对象创建一个矩形

 /*1.创建一个构造函数用来创建矩形*/
    function Rect(option){
        this._init(option)
    }

    /*2.给rect设置原型对象*/
    Rect.prototype = {
        _init:function(option){
            var option = option ||{};
            /*2.1设置属性*/
            /*2.11设置添加的父标签的id*/
             this.parentId = option.parentId;
            /*2.12设置宽度和高度*/
            this.width = option.width||100;
            this.height = option.height ||100;
            /*2.13设置位置*/
            this.left = option.left ||100;
            this.top = option.top ||100;
            /*2.14 设置其他属性*/
            this.background = option.background ||'blue';
            this.borderRadius = option.borderRadius ||10;
            this.border = option.border ||0;





        },
        /*设置显示方法*/
        render:function(){
            /*1.创建一个父标签,用来添加我们的矩形*/
            var parentNode = document.getElementById(this.parentId);
            var childremNode = document.createElement('div');
            parentNode.appendChild(childremNode);
            /*2.设置子标签的样式*/
            childremNode.style.position = 'absolute';
            parentNode.style.position = 'relative';
            childremNode.style.width = this.width +'px';
            childremNode.style.height = this.height +'px';
            childremNode.style.left = this.left +'px';
            childremNode.style.top = this.top +'px';
            childremNode.style.background = this.background;
            childremNode.style.borderRadius = this.borderRadius +'px';
            childremNode.style.border = this.border;




        }

    }

    /*创建一个矩形*/
//    this.width = option.width||100;
//    this.height = option.height ||100;
//    /*2.13设置位置*/
//    this.left = option.left ||100;
//    this.top = option.top ||100;
//    /*2.14 设置其他属性*/
//    this.background = option.background ||'blue';
//    this.borderRadius = option.borderRadius ||10;
//    this.border = option.border ||0;

    var myRect = new Rect({parentId:'main',width:200,height:100,left:200,top:200,background:'red',borderRadius:10,border:'1px solid #ccc'});
    alert(myRect);


    /*渲染*/
    myRect.render();

闭包的认识

  • 如果访问一个局部变量,但是出了作用域就访问不到,我们想要访问这个变量需要使用闭包
  • 闭包是在函数内部使用函数或者定义函数
  • 闭包作用域链条:就是子对象可以访问对象所有的属性,反之不可以
    就是访问变量的时候,会沿着作用域链条向上访问,不能反过来
  • 闭包的优点是延长变量的使用周期,缺点是耗费性能
//第一步
function sum(){
        var num = 10;
        var result = function(){
                  console.log(num);
        }
        return result;
}
var result =  sum();
//这样可以把变量通过返回函数的形式传递出来
//实际上内部函数可以匿名
function sun(){
        var num = 10;
        return function(){
                  console.log(num);
        }
} 
var result = sum();
console.log(num);
//第二种写法
sum()()
//这就是匿名函数传递参数

匿名函数自调

  • 匿名函数自调内部可以继续使用匿名函数自调
  • 当访问变量的时候,会先从自己的作用域访问对应的变量,如果没有,就沿着作用域链条向上访问,知道找到为止,如果没有返回未定义
  • 为了提高性能一般不要多层嵌套匿名函数自调
  • 为了提高性能一般不要使用全局变量
var num = 20;
(function(){
        (function(){
               console.log(num);
        })()
})(num)
  • 当使用全局变脸的时候,会把 window 中的所有的东西遍历一遍,直到找到对应的变量
for(var key in window){
}

访问变量的简单认识以及应用

//第一种写法,两次定义全局变量极其消耗性能,两次遍历 window
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn1');
//第二种写法,匿名函数的自调,只遍历一次 window 且是函数内部的局部变量
(function(){
        var d = document;
        var btn1 = d.getElementById('btn1');
        var btn2 = d.getElementById('btn2');
})()
//第二种写法的变形,将document当作参数传递进去
(functiojn(document){
        var btn1 = document.getElementById('btn1');
        var btn2 = document.getElementById('btn2');
})(document)

高级排他

var lis = document.getElementById('li');
//用来记录上一个移动到的位置
var lastIndex = 0;
for(var i = 0 ; i < lis.length;i++){
        (function(index){
                lis[i].onmouseover = function(){
                  lis[lastIndex].className = "";
                  this.className = 'curr';
                  lastIndex = index;
                  }
        })(i)
}

使用闭包实现数据截流

function throtte(delay,fn){
        var timer = null;
        return function(){
                clearTimerout(timer);
                timer = setTimerout(fn,delay)
        }
}

window.onresize = throtte(300,function(){
        alert(0);
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容

  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,703评论 2 17
  • 一、JavaScript基础知识回顾 1.1 JavaScript 1.1.1 javascript是什么? Ja...
    福尔摩鸡阅读 1,201评论 0 7
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,045评论 1 10
  • 函数的调用方式和 this 丢失 函数调用方式 普通函数方式调用 this - window 对象的...
    GodlinE阅读 217评论 0 1
  • js简介 Js是一种基于事件和对象驱动的解释性、松散性的语言。 一切皆对象 javascript 布兰登艾奇 ...
    塔库纳玛哈哈阅读 1,185评论 0 2