JavaScript入门指南---(六)、创建对象

面向对象编程

面向过程编程:特点是将数据保存到变量中,然后由一系列指令操作变量.每条指令(或一系列指令:函数),都能够创建,删除或修改数据,这使得看上去数据与程序代码在某种程度上是”分离”的.
面向对象编程(OOP):程序指令与其操作的数据密切相关联,OOP将程序的数据包含在被称为”对象”的结构中,每个对象都有自己的属性(数据)和方法(指令).
JS中并不会用到类的概念.

一,创建对象

创建直接实例

JS中有一个内置对象Object,利用它可以创建一个空白的对象.
  obj = new Object();
给对象添加属性,属性名为name:
  obj.name = “张三”;
给对象添加方法,方法名为eat:
首先要先定义一个方法:
  function eatFood(){

  }
然后将该方法附加到obj对象上:
  obj.eat = eatFood;
注:在将方法附加到对象上是,只需要写一个方法名就可以了,后面不需要跟上小括号,如果带上小括号,意思为先执行方法eatFood(),再将该方法的返回值赋值给obj的eat属性上

使用this关键字
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>oriented object programming</title>
        <script type="text/javascript">
            //通过内置的Object创建一个obj对象,这个对象是空白的,可以想象成一个得到了一个盒子但是盒子中没有内容
            obj = new Object();
            //定义一个obj的属性,起名为infoD,为infoD赋值后面的字符串
            obj.infoD = "我是infoD属性";
            //定义一个eatFood方法,这个方法是全局的,就像全局变量那样,在哪儿都可以用
            function eatFood () {
                //this在这里默认是指window对象
                //但是,当将eatFood附加给了obj的eat方法时
                //obj调用eat时,这里的this指的就是obj对象了
                alert(this.infoD);
            }
            //将eatFood方法,附加给obj对象上,命名为eat
            obj.eat = eatFood;

        </script>

    </head>
    <body>
        <input type="button" name="button1" id="button1" value="obj.eat" onclick="obj.eat()"/>

        <!--这个button,会默认调用window对象的eatFood方法
        这时候我们上面写的那个this指代的是window对象
        但是window对象并没有infoD这个属性,所以会显示undefined-->
        <input type="button" name="button2" id="button2" value="eatFood" onclick="eatFood()"/>


    </body>
</html>
匿名函数

前面的做法是,先创建出一个方法,再将该方法附加到某个对象上.下面是一种更简便的方式,称之为”匿名函数”.

obj.eat = function(){
  alert(this.infoD);
}
构造函数

构造函数,就是创建对象的模板,在这个模板中,创建一个对象时应该生成的属性,方法等都在这个模板中写好了,每次只要调用构造函数,就会创建出对应模子的实例对象.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>构造函数示例</title>
        <script type="text/javascript">
            //定义一个函数,这个函数就被当做构造函数来使用
            //因为每次调用这个函数,都会执行里面赋值属性,附加方法的操作.
            //就会构建出相同类型的不同对象
            //就是一堆长得一样的人,但是是不同的人,只是长的一样而已
            function peopleStructure () {
                this.infoName ="我是默认的名字";
                this.showInfoName = function(){
                    alert(this.infoName);
                }
                this.setInfoName = function(name){
                    this.infoName = name;
                }
            }
        </script>
    </head>
    <body>
    </body>
</html>
对象的实例化

在写过构造函数后,就可以使用这个构造函数创建对象的实例:

//下面代码是直接写在script标签中的,写在构造方法声明的下方
var obj = new peopleStructure();
//调用方法
obj.showInfoName();

示例演示:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>构造函数示例</title>
        <script type="text/javascript">
            //定义一个函数,这个函数就被当做构造函数来使用
            //因为每次调用这个函数,都会执行里面赋值属性,附加方法的操作.
            //就会构建出相同类型的不同对象
            //就是一堆长得一样的人,但是是不同的人,只是长的一样而已
            function PeopleStructure () {
                this.infoName ="我是默认的名字";
                this.showInfoName = function(){
                    alert(this.infoName);
                }
                this.setInfoName = function(name){
                    this.infoName = name;
                }
            }

            var obj1 = new PeopleStructure();

            var obj2 = new PeopleStructure();

        </script>
    </head>
    <body>
        <input type="button" name="button1" id="button1" value="点击显示obj1的infoName" onclick="obj1.showInfoName()" />
        <input type="button" name="button1" id="button1" value="点击显示obj2的infoName" onclick="obj2.showInfoName()" />
        <input type="button" name="button1" id="button1" value="修改obj1的infoName" onclick="obj1.setInfoName('我是修改后的infoName')" />

    </body>
</html>

构造函数演示

构造函数参数

在定义构造函数的时候,可以在小括号中设置参数,这样可以在每次创建对象实例的时候,根据需求传入不同的参数,生成不同的对象实例.

二,使用prototype扩展和继承对象

使用对象的主要优点之一是能够在不同的环境中重复使用已经编写好的代码.JS提供的机制能够基于已有的对象来修改对象,使其拥有新的方法和属性,甚至可以创建完全崭新的对象.
这就是”扩展”和”继承”.

扩展对象

当一个对象已经被实例化后,如果想使其具有新的方法和属性的话,需要使用关键字prototype.
注: prototype关键字,不止是将新方法和属性加入到这个已经被实例化的对象上,也加到了模板中,也就是说后面再建立该对象的实例,也会有新加入的属性或方法.

示例:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>关键字prototype示例</title>
        <script type="text/javascript">
            function Student() {
                this.name = "小李";
                this.showName = function() {
                    alert(this.name);
                }
                this.setName = function(name) {
                    this.name = name;
                }
            }

            var student1 = new Student();
            //prototype关键字,不止更改已经存在的实例,更是将模板也更改了,新建立的对象实例也会有该方法
            Student.prototype.doHome = function(homework){
                alert("我在做作业:"+homework);
            }

      //下面的操作是不起效果的,因为showName已经存在了,无法扩展同名操作(即使参数列表不同也不可以)
            Student.prototype.showName = function(){
                alert("我是扩展的showName方法");
            }
            var student2 = new Student();
        </script>
    </head>

    <body>
    <input type="button" name="button1" id="button1" value="学生一的名字" onclick="student1.showName()"/>
    <input type="button" name="button2" id="button2" value="学生一的新方法" onclick="student1.doHome('数学')"/>
    <input type="button" name="button3" id="button3" value="学生二的新方法" onclick="student1.doHome('语文')"/>
    </body>

</html>

prototype示例

继承对象

继承是值从一种对象类型创建另一种对象类型,新对象类型继承老对象类型的属性和方法,还可以添加自己的属性和方法.
通过这种方式,可以先设计出”通用”的对象类型,再不断细化它们来得到更特定的类型.
注: 是不是很像:细节应该依赖抽象—-依赖倒置原则
JS实现继承的方式也是通过关键字prototype.
因为prototype关键字,可以给对象添加新属性和新方法,那么可以通过prototype关键字,将已有的构造函数里的全部方法和属性都添加给新的对象.
那么这个新的对象也就有了原有构造函数中所有的方法和属性,这样就实现了继承.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>关键字prototype示例:继承</title>
        <script type="text/javascript">
            function Group(){
                this.name = "我是原有的";
                this.showName = function(){
                    alert(this.name);
                }
            }

            function Child(){
                this.name = "我是新的";
                this.showChild = function(){
                    alert(this.name);
                }
            }

            var child = new Child();

            Child.prototype = new Group();
            var afterPrototype = new Child();
        </script>
    </head>
    <body>
        <input type="button" name="button1" id="button1" value="点我显示child的showChild" onclick="child.showChild()"/>
        <!--这个点击事件发现是没有效果的,也就是说在继承Group的操作之前创建的child对象实例,是没有showName方法的-->
        <input type="button" name="button2" id="button2" value="点我显示child的showChild" onclick="child.showName()"/>
        <!--在继承Group操作后创建的afterPrototype对象实例,才有showName方法-->
        <input type="button" name="button3" id="button3" value="点我显示child的showName" onclick="afterPrototype.showName()"/>
    </body>
</html>
扩展JS内置的对象

关键字prototype还能够扩展JS内置的对象,下面举例扩展String的方法,返回字符串的倒序结果.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>关键字prototype:字符串倒序示例</title>
        <script type="text/javascript">
            String.prototype.backWords = function(){
                var result="";
                for (var i = 0; i < this.length; i++) {
                    result += this[this.length - i - 1];
                }
                alert(result);
            }
        </script>
    </head>
    <body>
        <!--得到用户输入的内容,也就是一个字符串,然后调用后添加的方法backWords-->
        <input type="button" name="button1" id="button1" value="gogogo" onclick="prompt().backWords()" />
    </body>
</html>

拓展JS内置对象示例

三,封装

封装是面向对象编程的一种能力,表示把数据和指令隐藏到对象内部.封装具体的实现方法,在不同的语言间有所区别.对应JS来说,在构造函数内部声明的变量,只能在对象内部使用,对于外部来说是不可见的,构造函数内部声明的函数也是这样的.
如果没有利用关键字this把变量和函数设置为对象的属性和方法,那么它们就不能从函数外部被调用,它们被称为”私有的”.
示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>构造函数中不使用this的结果</title>
        <script type="text/javascript">
            function Dog(){
                function eat(){
                    alert("吃掉了");
                }

                this.run = function(){
                    alert("跑掉了");
                    //在构造函数Dog内部使用
                    eat();
                }
            }

            var dog = new Dog();
            //run方法是可以执行的
            dog.run();
            //eat方法是不能执行的,因为没有使用this将方法eat设置成对象的方法,只是单单的做了一个声明
            //那么eat方法就只能在构造函数内部使用
            dog.eat();
        </script>
    </head>
    <body>
    </body>
</html>

封装示例构造函数中不使用this
错误信息
错误信息2

四,使用功能检测

主要是为了适配各种各样不同的浏览器.

可以使用if语句来检测
//如果方法getElementById不可用,那么if的判断会得到false
if(document.getElementById){
  element = document.getElementById('id');
}else {
  //TODO
}
使用typeof操作符检测函数是否存在
if(typeof document.getElementById() == 'function'){
  //TODO  使用getElementById方法
}else {
  //TODO 做一些其他的操作
}
typeof操作符的返回值

typeof会返回一个用来表示表达式的数据类型的字符串.

意义
“number”操作数是一个数值
“string”操作数是一个字符串
“boolean”操作数是一个布尔类型
“object”操作数是一个对象
null操作数是null
undefined操作数未定义
function操作数是一个方法
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值