菜鸟学习第二十三天js对象模型和function对象,js中的继承

本文介绍了JavaScript中的函数作为对象的特性,包括没有函数重载、函数的arguments属性和length属性。讨论了JavaScript的原始数据类型和typeof运算符。讲解了对象的创建、数组的sort方法以及对象的定义和继承方式,包括构造函数、原型链和组合使用构造函数与原型。强调了正确处理对象共享和属性初始化的重要性。

1.在js中,函数(function)就是对象,后面的名字就是对象的引用
2.在js中,没有方法(函数)重载的概念
3.所以假设有同名的function函数,那么执行的永远是后面的那个同名function函数,因为对象被重新赋值了,一般采用第二种:

<script>
        function add() {
            alert("30");
        }
        var add=function () {
            alert("30");
        }
    </script>

4.js中变量或者参数或者函数没有定义值,那么返回的是Undefined类型的值:undefined,js中有一个Function对象,所有自定义的函数都是Function类型的,比如:

<script type="text/javascript">


        var add=new Function("number","number2","alert(number+10);alert(number2+10);");//Function接收,以字符串形式的参数和函数体,先传入参数,最后传函数体
        add(20,30);
    </script>

5.js中每个函数都有个隐式对象(属性)arguments[参数],参数从0开始分别代表第一个参数到最后一个参数,注意是实际赋值的参数,不受函数本身参数影响,比如

<script type="text/javascript">

        function add(number1,number2)
        {
            alert(arguments[0]);
            alert(arguments[1]);
            alert(arguments[2]);
        }
        add(20,30,40);
    </script>

比如arguments.length返回的是传入参数的个数,注意没有()。
6.每个函数对象都有一个length属性,表示该函数期望接受的参数格式,它与函数argument不同,argument.length表示函数实际接受的参数
7.js中有五种原始数据类型:
Undefined:未定义,数据类型只有一个undefined
Null:数据类型只有一个null,undefined实际上是从null派生出来的。
Boolean:数据类型只有true和false
Number:
String:单引号和双引号都代表字符串,js中没有char数据类型
7.typeof是一元运算符,后跟变量的名称,用于获取变量的数据类型,其返回值有5个:undefined,boolean,number,string,object
8.强制类型转换:在javascript中有3种强制类型转换:Boolean(value),当value为0时为false,Number(value),String(value).当前面没有new时代表强制转换,有代表对象
9.在js中,所有的对象都是从object对象继承过来的,object中的属性是不可枚举的,因此无法通过for。。in得到其属性。
10.定义数组
对于js数组的sort方法来说,它会先将待排序的内容转换为字符串(调用toString()方法),按照字符串的先后顺序进行排序。

var array=new Array();
        array.push(1);
        array.push(2);
        var array=[1,3,25];
        array.sort();//这是不可靠的,所以我们要自定义比较函数
        alert(array)
var array=[1,3,25];
function compare(num1,num2) {
    var temp1=parseInt(num1);
    var temo2=parseInt(num2);
    if (temp1==temo2)
    {
        return 0;

    }
    if (temp1<temo2)
    {
        return -1;
    }
    else
    {
        return 1;
    }
}
array.sort(compare);//第一种方法,结合上面的compare函数
// array.sort(function (a, b) { return a-b; });//第二种方式采用匿名函数的方式,如果返回值小于0代表a小于b,等于0代表相等,大于0代表a大于b,把b换到前面
alert(array);

11,js中定义对象:

 var object=new Object();//js中定义对象的第一种方式
        object.username="zhangsan";
        object["password"]="12345";//添加属性的2种方式["属性名"]或者对象.属性名
        object.sex="男";
        alert(object.username);
        alert(object.password);
        alert(object["sex"]);
        delete object.username;//username属性已经从object中删除
        var object={username:“zhangsan”,password:123};//js中定义对象第二方式也是最常用的方式

定义属性和定义方法:
1.第一种方式

<script type="text/javascript">

        var object=new Object();
        object.name="zhangsan";
        object.showname=function (name) {   //决定定义的是属性还是函数时根据右边决定的,如果右边是function,那么定义的就是一个函数
            this.name=name;
            alert(this.name);

        }
        object.showname("lisi");

    </script>

2.第二种方式:工厂方式

 <script type="text/javascript">

   function createObject() {
       var object=new Object();
       object.name="zhangsan";
       object.password="123";
       object.getall=function () {
           alert(this.name+","+this.password)
       }
       return object;
   }
   var object1=createObject();
   object1.getall();
    </script>

传入参数:

 <script type="text/javascript">

   function createObject(username,password) {
       var object=new Object();
       object.name=username;
       object.password=password;
       object.getall=function () {
           alert(this.name+","+this.password)
       }
       return object;
   }
   var object1=createObject("zhangsan","123");
   object1.getall();
    </script>

上面这种工厂模式弊端在于每创建一个对象就会有一个getall方法,占用内存,所以我们将方法提取出来,让创建的多个对象中相同的方法共享,因为方法有可能是相同的,属性是不同的,如下:

   <script type="text/javascript">
function getall() {
    alert(this.name+","+this.password)
}
   function createObject(username,password) {
       var object=new Object();
       object.name=username;
       object.password=password;
       object.getall=getall;                                     //注意这边调用方法不能加()
       return object;
   }
   var object1=createObject("zhangsan","123");
   object1.getall();                                                    //注意这边调用方法需要加()
    </script>

3.构造函数方式:

<script type="text/javascript">

        function person() {
            //在执行第一行代码前,js引擎为我们生成了一个对象,这个对象就是当前创建的对象也就是this
            this.name="zhangsan";
            this.password="1234";
            this.getall=function () {
                alert(this.name+","+this.password)
            }
//相比工厂模式这里没有return语句,实际上这里有个隐藏的return语句,当我们new一个对象时将生成的对象返回并赋给下面的person1
        }
        var person1=new person();  //只有当我们用new方式生成一个对象的时候,js引擎才会为我们完成上面那个注解的事情
        person1.getall();
    </script>

4.原型(“prototype”)方式:prototype是js Object中的一个属性

<script type="text/javascript">

        function Person() {

        }
        Person.prototype.username="zhansan";//使用对象的原型来为对象设置属性和方法
        Person.prototype.password="1234";
        Person.prototype.getall=function () {
            alert(this.username+","+this.password)
        }
        var person1=new Person();
        var person2=new Person();
        person1.username="lisi";//修改对象中的属性
        person1.getall();
        person2.getall();
    </script>

“单纯”使用原型方式定义类无法在构造函数中为属性赋初始值,只能在生成对象后再去改变属性值
问题:
1.没办法传参数
2.会导致程序错误
总结:如果使用原型方式定义对象,那么生成的所有对象会共享原型中的属性(如果属性是一个常量,比如上面的username,那么我们改完之后person1的username就指向了新的常量“lisi”,但如果username是一个对象,比如数组对象,那么我们修改之后,person1和person2会共享这一个对象,这个属性就变成所有person对象共享的了),所有我们一般将原型和其他方法结合起来使用。
5.原型和构造方法结合使用:将属性放到构造函数中,让所有对象单独一份,将方法放到原型中,让所有对象共享一个方法

<script type="text/javascript">

        function Person() {
            this.username=new Array();
            this.password="1234";
        }

        Person.prototype.getall=function () {
            alert(this.username+","+this.password)
        }
        var person1=new Person();
        var person2=new Person();
        person1.username.push("zhansan");
        person2.username.push("lisi");
        person1.getall();
        person2.getall();
    </script>

6.第五种动态原型方式:

  <script type="text/javascript">

        function Person() {
            this.username=new Array();
            this.password="1234";
            if (typeof Person.flag=="undefined")
            {
                Person.prototype.getall=function () {
                alert(this.username+","+this.password);
            }
             Person.flag=true;
            }
        }
        var person1=new Person();
        var person2=new Person();
        person1.username.push("zhansan");
        person2.username.push("lisi");
        person1.getall();
        person2.getall();
    </script>

12.js中的继承
继承第一种方式:对象冒充,可以实现多继承,但不推荐,因为如果2个父类中有相同属性或者方法,后继承的会将前面继承的覆盖

  <script type="text/javascript">

        function Parent(username) {
            this.username=username;
            this.showname=function () {
                alert(this.username);
            }
        }
        function Child(username,password) {
            this.method=Parent;          //1 通过1,2,3这三行代码来实现继承,继承了父类的所有属性和方法,method是定义的属性
            this.method(username);       //2
            delete method;               //3
            this.password=password;
            this.showword=function () {
                alert(this.password)
            }
        }
        var parent=new Parent("zhangsan");
        var child=new Child("lisi","123");
        parent.showname();
        child.showname();
        child.showword();
    </script>

继承的第二种方式:call方法方式,call方法是定义在Function对象中的方法,因此我们定义的每个函数都拥有该方法,可以通过函数名来调用call方法,call方法的第一个参数会被传递给函数中的this,从第二个参数开始,逐一给函数参数赋值。

  <script type="text/javascript">

        function test(str,str1) {
            alert(this.name+","+str);
            
        }
        var object=new Object();
        object.name="zhangsan";
        //test.call相当于调用了test这个函数
        test.call(object,"lisi","wangwu");//将object赋给了this,即第一个参数永远传递给了调用者test的this
    </script>

这种方式使用较多:

<script type="text/javascript">

        function Parent(username) {
            this.username=username;
            this.showname=function () {
                alert(this.username);
            }
        }
        function Child(username,password) {
            Parent.call(this,username);               //this代表当前对象Child,只需要这一步就实现了继承,然后可以使用父类的属性和方法了
            this.password=password;
            this.showpassword=function () {
                alert(this.username+","+this.password);
            }
        }
        var parent=new Parent("zhangsan");
        var child=new Child("lisi","123");
        parent.showname();
        child.showname();
        child.showpassword();
    </script>

第三种方式;使用apply方法实现对象继承,apply方法也是定义在Function对象里面的

<script type="text/javascript">

        function Parent(username) {
            this.username=username;
            this.showname=function () {
                alert(this.username);
            }
        }
        function Child(username,password) {
            Parent.apply(this,new Array(username));//和call的区别在于第二个参数开始时一个new Array,也可以写成[username,...]如果有多个参数,逗号隔开
            this.password=password;
            this.showpassword=function () {
                alert(this.username+","+this.password);
            }
        }
        var parent=new Parent("zhangsan");
        var child=new Child("lisi","123");
        parent.showname();
        child.showname();
        child.showpassword();
    </script>

第四种方式:原型链方式,这种方式无法传递参数,所以我们改进

 <script type="text/javascript">

      function Parent() {

      }
      Parent.prototype.name="zhangsan";
      Parent.prototype.getname=function () {
          alert(this.name)
      }
      function Child() {

      }
      Child.prototype=new Parent();
      Child.prototype.password="123";
      Child.prototype.getworld=function () {
          alert(this.password);
      }
      var child=new Child();
      child.getname();
      child.getworld();

    </script>

5.改进:混合方式,也是将属性定义在构造函数,方法定义在prototype(推荐)

<script type="text/javascript">

      function Parent(name) {
         this.name=name;
      }

      Parent.prototype.getname=function () {
          alert(this.name)
      }
      function Child(name,world) {

          Parent.call(this,name);  //使用call继承属性
          this.world=world;
      }
      Child.prototype=new Parent();      //使用原型继承方法
      Child.prototype.getworld=function () {
          alert(this.world);
      }
      var child=new Child("zhangsan","1234");
      child.getname();
      child.getworld();

    </script>

练习:Triangle三角形继承自Shape图形

  <script type="text/javascript">

      function Shape(edge,bottom,height) {

          this.edge=edge;//图形的边
          this.bottom=bottom;//图形的长
          this.height=height;//图形的高

      }
      Shape.prototype.getedge=function () {
          return this.edge;

      }
      Shape.prototype.getarea=function () {
          return -1;
      }
      function Triangle(bottom,height) {
          Shape.call(this,3,bottom,height);

      }
      Triangle.prototype=new Shape();
      Triangle.prototype.getarea=function () {
          return 0.5*this.bottom*this.height;
      }
      var triangle=new Triangle(5,10);
      alert(triangle.getedge());
      alert(triangle.getarea());
    </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值