js基础知识(第二篇)

面向对象概念

面向对象(Object Oriented,OO)是软件开发方法。面向对象的概念和应用已超越了
程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、
分布式系统、网络管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物,是一种高级的编程思想。
面向对象是一种思想,很多种语言之中都有面向对象的思想,这种思想已经不同于面向过程的逻辑了。
提起对象,先做一个简单的回忆:
回顾对象:javascript中万事万物皆对象。
不用了解其中内部机制, 但是只要会用就可以了。 比如之前学习过的DOM,BOM,对象Date对象是最典型的一个实例:

Date.get   ||   Date.set系列问题。
DOM.appendChild( )....

面向对象:只关注对象提供的功能, 不关注内部的细节。

面向对象
面向对象的特点:(封装,继承,多态)
抽象:抽出和问题相关的东西;
对学生而言:学生管理系统:这时候关注的点在于:学生成绩,学生分数;
世纪佳缘:需要知道,性别年龄,三维;

封装:
1.用对象:
2.写对象(类):
继承:
单继承
多重继承:继承好多份遗产;

回顾对象的组成:
方法 属性
什么是方法和属性那?

var timer=null
DOM.timer=null

测试证明:
属性其实就是变量!
婚前婚后的差别;
婚前:谁都不属于谁。

1. 构造函数的使用

  1. js提供的构造函数 New Date();
    2)自己定义的构造函数

2. 构造函数和对象的关系
New 加构造函数创建对象
3. 使用Json创建对象
{name:”wangcai”,age:2 }
4. 面相对象和面相过程的区别
面向过程是一件事“该怎么做“,面向对象是一件事“该让谁来做”,然后那个“谁”就是对象,他要怎么做是他自己的事,反正最后一群对象合力能把事做好就行了。
面向对象: 狗.吃(屎)
面向过程: 吃.(狗,屎)

1. 类的概念
类的概念 : 类是具有相同属性和方法的一组对象的集合。为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和方法两个主要部分
2. 类和对象
类与对象的关系就如模具和铸件的关系,类的实例化结果就是对象,而对一类对象的抽象就是类。类描述了一组有相同特性( 属性 ) 和相同行为 ( 方法 ) 的对象。
3. JSON字符串和对象直接的转换

var A = '{  "a": 1 , "b" : "hello"}';
JSON.parse(A);

JSON.stringify();

eval 函数  
eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。

eval("x=10;y=20;document.write(x*y)")
document.write(eval("2+2"))
var x=10

document.write(eval(x+17))
eval("("+A+")");//把字符串 转为对象 

localstorge

什么是localStorage
在HTML5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,
解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k),
localStorage中一般浏览器支持的是5M大小,这个在不同的浏览器中localStorage会有所不同

localStorage的优势
1、localStorage拓展了cookie的4K限制
2、localStorage会可以将第一次请求的数据直接存储到本地,这个相当于一个5M大小的针对于前端页面的数据库,相比于cookie可以节约带宽,但是这个却是只有在高版本的浏览器中才支持的

localStorage的局限
1、浏览器的大小不统一,并且在IE8以上的IE版本才支持localStorage这个属性
2、目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换localStorage的写入,localStorage的写入有三种方法。 localStorage只支持string类型的存储

 var storage=window.localStorage;
        //写入a字段
        storage["a"]=1;
        //写入b字段
        storage.a=1;
        //写入c字段
        storage.setItem("c",3);

三种对localStorage的读取,其中官方推荐的是getItem\setItem这两种方法对其进行存取

  //第一种方法读取
        var a=storage.a;
        console.log(a);
        //第二种方法读取
        var b=storage["b"];
        console.log(b);
        //第三种方法读取
        var c=storage.getItem("c");
        console.log(c)

localStorage的修改
改这个步骤比较好理解,思路跟重新更改全局变量的值一样

var storage=window.localStorage;
//写入a字段
storage["a"]=1;
storage.a=4; //修改
console.log(storage.a)

localStorage的删除
将localStorage中的某个键值对删除

storage.setItem("c",3);
console.log(storage);
storage.removeItem("a");

将localStorage的所有内容清除

storage.clear();

localStorage其他注意事项
一般我们会将JSON(js中的对象)存 入localStorage中,但是在localStorage会自动将localStorage转换成为字符串形式
这个时候我们可以使用JSON.stringify()这个方法,来将JSON转换成为JSON字符串

var data={
        name:'zhangsan',
        sex:'man',
    };
    var d=JSON.stringify(data);
    storage.setItem("data",d);
    //将JSON字符串转换成为JSON对象输出
    var json=storage.getItem("data");
    var jsonObj=JSON.parse(json);

Math date(重点)对象常见API 三角函数

Math是 JavaScript 的原生对象,提供各种数学功能。该对象不是构造函数,不能生成实例,所有的属性和方法都必须在Math对象上调用。
Math对象的属性,提供以下一些数学常数。(了解)

Math.E:常数e。
Math.PI:常数 Pi。

Math.abs方法返回参数值的绝对值。

Math.abs(1) // 1
Math.abs(-1) // 1

Math.max方法返回参数之中最大的那个值,Math.min返回最小的那个值。如果参数为空, Math.min返回Infinity, Math.max返回-Infinity。

Infinity 用于存放表示正无穷大的数值
Math.max(2, -1, 5) // 5
Math.min(2, -1, 5) // -1
Math.min() // Infinity  
Math.max() // -Infinity

Math.floor方法小于参数值的最大整数(地板值)。

Math.floor(3.2) // 3
Math.floor(-3.2) // -4

Math.ceil方法返回大于参数值的最小整数(天花板值)。

Math.ceil(3.2) // 4
Math.ceil(-3.2) // -3


Math.round方法用于四舍五入。
Math.round(0.1) // 0
Math.round(0.5) // 1
Math.round(0.6) // 1
Math.round(-1.1) // -1
Math.round(-1.5) // -1
Math.round(-1.6) // -2

Math.pow方法返回以第一个参数为底数、第二个参数为幂的指数值。

// 等同于 2 ** 2
Math.pow(2, 2) // 4
// 等同于 2 ** 3
Math.pow(2, 3) // 8
Math.sqrt方法返回参数值的平方根。如果参数是一个负值,则返回NaN。
Math.sqrt(4) // 2
Math.sqrt(-4) // NaN

三角函数

Math对象还提供一系列三角函数方法
Math.sin():返回参数的正弦(参数为弧度值)
Math.cos():返回参数的余弦(参数为弧度值)
Math.tan():返回参数的正切(参数为弧度值)
30*Math.PI/180   角度转为弧度
Math.sin(0) // 0
Math.cos(0) // 1
Math.tan(0) // 0
Math.sin(Math.PI / 2) // 1

Math.random()返回0到1之间的一个伪随机数,可能等于0,但是一定小于1。
Math.random() // 0.7151307314634323
任意范围的随机整数生成函数如下。

function getRandomInt(min, max) {
  return parseInt(Math.random() * (max - min + 1)) + min;
}
getRandomInt(1, 6) // 5

Date对象是 JavaScript 原生的时间库。它以1970年1月1日00:00:00作为时间的零点,可以表示的时间范围是前后各1亿天(单位为毫秒)
日期对象创建
Date可以当作构造函数使用。对它使用new命令,会返回一个Date对象的实例。如果不加参数,实例代表的就是当前时间。

var today = new Date();
today
// "Tue Dec 01 2015 09:34:43 GMT+0800 (CST)"

// 等同于
today.toString()
// "Tue Dec 01 2015 09:34:43 GMT+0800 (CST)"

对Date实例求值,返回的是一个字符串,代表该实例对应的时间。

日期处理

 oDate.getDate()      返回一个月中的某一天 (1 ~ 31)
 oDate.getDay()       返回一周中的某一天 (0 ~ 6)
 oDate.getMonth()  返回月份 (0 ~ 11)
 oDate.getFullYear() 以四位数字返回年份
作为构造函数时,Date对象可以接受多种格式的参数,返回一个该参数对应的时间实例。

// 参数为时间零点开始计算的毫秒数


new Date(1378218728000)(最常用)


// Tue Sep 03 2013 22:32:08 GMT+0800 (CST)
/ 参数为多个整数,
// 代表年、月、日、小时、分钟、秒、毫秒
new Date(2013, 0, 1, 0, 0, 0, 0)

// Tue Jan 01 2013 00:00:00 GMT+0800 (CST)
参数也可以是一个字符串(最常用)

日期字符串应该符合 RFC 2822 和 ISO 8061 这两个标准,即YYYY-MM-DDTHH:mm:ss.sssZ格式

new Date('2013-2-15')
new Date('2013/2/15')
new Date('02/15/2013')
new Date('2013-FEB-15')
new Date('FEB, 15, 2013')
new Date('Feberuary, 15, 2013')
new Date('15 Feb 2013')
new Date('15, Feberuary, 2013') 

上面多种日期字符串的写法,返回的都是同一个时间

日期处理

 oDate.getDate()      返回一个月中5的某一天 (1 ~ 31)
 oDate.getDay()       返回一周中的某一天 (0 ~ 6)
 oDate.getMonth()  返回月份 (0 ~ 11)
 oDate.getFullYear() 以四位数字返回年份
oDate.getHours()    返回当前小时(0-23)
oDate.getMinutes() 返回当前分钟 (0 ~ 59)
oDate.getSeconds()       返回当前秒(0 ~ 59)
oDate.getMillisenconds()  返回当前毫秒(0 ~ 999)

注意,月份从0开始计算,但是,天数从1开始计算。另外,除了日期的默认值为1,小时、分钟、秒钟和毫秒的默认值都是0。

new Date(2013, 15)
// Tue Apr 01 2014 00:00:00 GMT+0800 (CST)

oDate.getTime()       返回1970年1月1日至今的毫秒数
oDate.setDate()      设置月中的某一天 (1 ~ 31)
 oDate.setMonth()  设置月份 (0 ~ 11)
 例:oDate.setMonth(9);   alert(oDate.getMonth())
oDate.setFullYear()设置年份(四位数)
oDate.setHours()             设置小时(0-23)
oDate.setMinutes()          设置分钟 (0 ~ 59)
oDate.setSeconds()          设置秒(0 ~ 59)
oDate.setMillisenconds()  设置毫秒(0 ~ 999)
oDate.setTime()                 设置1970年1月1日至今的毫秒数

这些参数如果超出了正常范围,会被自动折算。比如,如果月设为15,就折算为下一年的4月

日期的运算
类型自动转换时,Date实例如果转为数值,则等于对应的毫秒数;如果转为字符串,则等于对应的日期字符串。所以,两个日期实例对象进行减法运算时,返回的是它们间隔的毫秒数;进行加法运算时,返回的是两个字符串连接而成的新字符串。

var d1 = new Date(2000, 2, 1);
var d2 = new Date(2000, 3, 1);

d2 - d1
// 2678400000
d2 + d1
// "Sat Apr 01 2000 00:00:00 GMT+0800 (CST)Wed Mar 01 2000 00:00:00
   

静态方法
Date.parse方法用来解析日期字符串,返回该时间距离时间零点(1970年1月1日 00:00:00)的毫秒数。
日期字符串应该符合 RFC 2822 和 ISO 8061 这两个标准,即YYYY-MM-DDTHH:mm:ss.sssZ格式,其中最后的Z表示时区。但是,其他格式也可以被解析,请看下面的例子。

Date.parse('Aug 9, 1995')
Date.parse('January 26, 2011 13:51:50')
Date.parse('Mon, 25 Dec 1995 13:30:00 GMT')
Date.parse('Mon, 25 Dec 1995 13:30:00 +0430')
Date.parse('2011-10-10')
Date.parse('2011-10-10T14:48:00')

运动也可以叫做动画

1:运动原理
通过连续不断的改变物体的位置,而发生移动变化。
使用setInterval实现。
匀速运动:速度值一直保持不变。
多物体同时运动:将定时器绑设置为对象的一个属性。
注:物体每次运动都应该把之前的定时器清除掉。

//box为绝对定位
var speedX = 2
 box.timer = setInterval(function(){
      box.style.left = box.offsetLeft + speedX +'px';
},80)

2:边界处理
遇到边界是应该停止掉还是反弹,方向相反。
改变物体运动方向:将物体的速度值取反。

//边界属性  浏览器视口宽高
//返回当前视口的高度(即浏览器窗口的高度)
console.log(document.documentElement.clientHeight)
console.log(document.documentElement.clientWidth)

// 网页总高度     body默认有margin,记得重置
console.log(document.body.clientHeight)
console.log(document.body.clientWidth)

var speedX = 2
 box.timer = setInterval(function(){
      box.style.left = box.offsetLeft + speedX +'px';
     //左右边界
     if(box.offsetLeft <=0 || box.offsetLeft >= cWidth - box.offsetWidth){
          speedX = -speedX;
     }
},80

3:加速减速
加速:速度越来越快。
减速:速度越来越慢。

box.timer = setInterval(function() {
     speedX = speedX + 2;
     div.style.left = div.offsetLeft + speedX + 'px';
}, 50);

4:抛物线
水平方向有一速度,垂直方向有一速度,并做自由落体。

var speedY = 0;
var speedX = 10;
// x 方向  匀速
// y 方向  匀加速
box.timer = setInterval(function() {
     speedY += 9.8
     box.style.left = box.offsetLeft + speedX + 'px';
     box.style.top = box.offsetTop + speedY + 'px'
}, 80)

5:透明度的变换
box逐渐消失
//使用css将box的opacity 设置为1

var op = 1;
box.timer = setInterval(function() {
     op = op - 0.01;
     div.style.opacity = op
     //或者
     //div.style.opacity = getComputedStyle(div).opacity - 0.01;
}, 80);

6:缓冲运动
速度一开始很大,然后慢慢变小,比较类似自然界中的缓冲运动

//一开始box 在 (0,0)位置,我们将box运动到(300,0)位置

var target = 300; //目标位置
box.timer = setInterval(function() {
     //target - div.offsetLeft 是元素距离目标的路程,随着越来越靠近目标,这个值就越来越小,如果把这个值当做速度,速度一开始很大,然后慢慢变小,比较类似自然界中的缓冲运动。如果把这个值直接当速度,一下子就到,所以除以8以后当做速度
     var speed = (target - div.offsetLeft) / 8;
     //所以要对速度向上取整得到速度1,当speed小于0.375的时候,div就不会移动了
     speed = Math.ceil(speed);
     box.style.left = div.offsetLeft + speed + 'px';
     if(box.offsetLeft == target) {
          //到达目标清除定时器
          clearInterval(box.timer);
     }
}, 30);

考虑到运动的时候可能往前,也可以能往后,增加判断
//一开始box 在 (0,0)位置,我们将box运动到(300,0)位置

var target = 300; //目标位置
div.timer = setInterval(function() {
     var speed = (target - div.offsetLeft) / 8;
     //当speed小于0.375的时候,div就不会移动了
     //所以要对速度向上取整或者向下取整
     if(speed > 0) {
          //speed大于0 说明是往前运动
          //当speed小于0.375的时候,div就不会移动了
          //所以要对速度向上取整或者向下取整
          speed = Math.ceil(speed);
     } else {
          //speed大于0 说明是往后运动
          speed = Math.floor(speed);
     }
     div.style.left = div.offsetLeft + speed + 'px';
     if(div.offsetLeft == target) {
          clearInterval(div.timer);
     }
}, 30);

上面代码封装为函数

function animate(div,targetX) {
    var target = targetX;
    div.timer =  setInterval(function () {
        var speed = (target - div.offsetTop)/8;
        speed = (speed>0? Math.ceil(speed): Math.floor(speed));
        div.style.top = div.offsetTop + speed +'px';
        if(div.offsetTop == target){
            clearInterval(div.timer);
        }
    },30);
}

7:多属性缓冲运动函数封装
上面的封装只能固定的在x方向做动画
如果想让一个div 从一个点运动到另一个点,怎么办?
比如从(0,0)到(100,200)
这个时候我们把第二个参数改为一个这样的对象 {left:100;top:200}

function animate(div, obj) {
     //{left:100;top:200}
     //{left:100}
     clearInterval(div.timer);
     div.timer = setInterval(function() {
          var flag = true; //假设已经到了目的地

          for(var key in obj) {
              console.log(key) //left   top
              console.log(obj[key]) //300
              var target = obj[key]; //目标值
              // getComputedStyle['left']  元素left 属性 当前值
              var speed = (target - parseInt(getComputedStyle(div)[key])) / 8;
              speed = (speed > 0 ? Math.ceil(speed) : Math.floor(speed));
              div.style[key] = parseInt(getComputedStyle(div)[key]) + speed + 'px';
              if(parseInt(getComputedStyle(div)[key]) != target) {
                   flag = false;
              }

          }

          //必须等到所有的 属性都到达目的地 才能结束定时器
          if(flag == true) {
              clearInterval(div.timer);
          }

     }, 30);
}

上面咱们就封装了一个运动函数,也可以叫运动框架,说白了,就是封装一次以后,我们再做一些动画就非常方便!前人栽树后人乘凉,便是框架的好处!

如果想让框架支持透明度动画怎么办呢?无非是增加更多的判断

闭包和继承

1.什么是闭包
闭包就是能够读取其他函数内部变量的函数。在JS中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解为”定义在一个函数内部的函数”。

function fn() {
     var b = 1;
     //闭包
     function box() {
          //
          console.log(b);
     }
     //返回一个函数,这个函数就是一个闭包
     return box;
}
//res 就是 box 函数
var res = fn();
//2秒以后调用res函数,还是能打印b的值,闭包能让局部变量常驻内存
setTimeout(function() {
     res();
}, 2000);

2.闭包的特点
1:可以读取函数内部的变量。
变量的作用域无非就是两种:全局变量和局部变量。
JS语言的特殊之处,就在于函数内部可以直接读取全局变量。另一方面,函数外部自然无法读取函数内的局部变量
2:让这些变量的值始终保存在内存中

闭包的应用场景
1:函数作为返回值。

function box() {

     var n = 1; //
     function cox() {
          n++;
          return n;
     }

     return cox;

}
//res 就是一个闭包 ,n像是一个全局变量
var res = box();

console.log(res()); //2
console.log(res()); //3

2:函数作为参数被传递
本质是在子类中,调用父类构造函数,从而让子类拥有父类的属性和方法

call/apply方法
all和apply都是为了改变某个函数运行时的context即上下文而存在的,换句话说,就是为了改变函数内部this的指向。
二者作用完全一样,只是接受参数的方式不太一样。

fn.call(obj, arg1, arg2 [, argN]);
 call方法是Function类中的方法
  call方法的第一个参数的值赋值给类(即方法)中出现的this
  call方法的第二个参数开始依次赋值给类(即方法)所接受的参数

注意:调用函数的call或者apply方法相当于是调用函数

       function box(a,b){
                   console.log(this,a,b)
              }
             var arr = [1111];
              //使用arr改变的 box中this
              box.call(arr,1,3)
			fn,.apply(obj, [arg1, arg2,…, argN]);

apply以数组的形式传参,call是以列表的形式
apply方法接受2个参数,
A、第一个参数与call方法的第一个参数一样,即赋值给类(即方法)中出现的this
B、第二个参数为数组类型,这个数组中的每个元素依次赋值给类(即方法)所接受的参数

       function box(a,b){
                   console.log(this,a,b)
              }

              var arr = [1111];

              //使用arr改变的 box中this
              box.apply(arr,[2,4])

			利用apply使用math的min和max 方法
              var arr1 = [1,2,3,4,5,6,6,45,45];
              console.log(Math.min.apply(null,arr1));
              console.log(Math.max.apply(null,arr1));

call/apply继承

prototype原型
大部分面向对象的编程语言,都以“类”(class)为基础,实现对象的继承。JavaScript 语言不是如此,它的对象继承以“原型对象”(prototype)为基础。

JavaScript 通过构造函数生成新对象,因此构造函数可以视为对象的模板。实例对象的属性和方法,可以定义在构造函数内部。

function Cat(name, color) {
  this.name = name;
  this.color = color;
  this.meow = function () {
    console.log('喵喵');
  };}
var cat1 = new Cat('大毛', '白色');
var cat2 = new Cat('二毛', '黑色');
cat1.meow === cat2.meow// false
 上面代码中,Cat函数是一个构造函数,函数内部定义了name属性和color属性,所有实例对象(上例是cat1)都会生成这两个属性,即这两个属性会定义在实例对象上面。

通过构造函数为实例对象定义属性,虽然很方便,但是有一个缺点。同一个构造函数的多个实例之间,无法共享属性,从而造成对系统资源的浪费。
cat1和cat2是同一个构造函数的两个实例,它们都具有meow方法。由于meow方法是生成在每个实例对象上面,所以两个实例就生成了两次。也就是说,每新建一个实例,就会新建一个meow方法。这既没有必要,又浪费系统资源,因为所有meow方法都是同样的行为,完全应该共享。

这个问题的解决方法,就是 JavaScript 的原型对象(prototype)。

prototype的概念
每一个构造函数都有一个prototype属性,这个属性会在生成实例的时候,成为实例对象的原型对象。

JavaScript 的每个对象都继承另一个对象,后者称为“原型”(prototype)对象。
一方面,任何一个对象,都可以充当其他对象的原型;另一方面,由于原型对象也是对象,所以它也有自己的原型。null也可以充当原型,区别在于它没有自己的原型对象。

JavaScript 继承机制的设计就是,原型的所有属性和方法,都能被子对象共享。

下面,先看怎么为对象指定原型。
每一个构造函数都有一个prototype属性,这个属性会在生成实例的时候,成为实例对象的原型对象

function Animal(name) {
  this.name = name;
}
Animal.prototype.color = 'white';
var cat1 = new Animal('大毛');
var cat2 = new Animal('二毛');
cat1.color // 'white'
cat2.color // 'white'

上面代码中,构造函数Animal的prototype对象,就是实例对象cat1和cat2的原型对象。原型对象上添加一个color属性,结果,实例对象都继承了该属性。
原型对象的属性不是实例对象自身的属性。只要修改原型对象,变动就立刻会体现在所有实例对象上。

Animal.prototype.color = 'yellow';
cat1.color // "yellow"
cat2.color // "yellow"

上面代码中,原型对象的color属性的值变为yellow,两个实例对象的color属性立刻跟着变了。这是因为实例对象其实没有color属性,都是读取原型对象的color属性。也就是说,当实例对象本身没有某个属性或方法的时候,它会到构造函数的prototype属性指向的对象,去寻找该属性或方法。这就是原型对象的特殊之处。
如果实例对象自身就有某个属性或方法,它就不会再去原型对象寻找这个属性或方法。

总结一下,原型对象的作用,就是定义所有实例对象共享的属性和方法。这也是它被称为原型对象的原因,而实例对象可以视作从原型对象衍生出来的子对象

原型链继承

原型链
对象的属性和方法,有可能定义在自身,也有可能定义在它的原型对象。由于原型本身也是对象,又有自己的原型,所以形成了一条原型链(prototype chain)。比如,a对象是b对象的原型,b对象是c对象的原型,以此类推。

如果一层层地上溯,所有对象的原型最终都可以上溯到Object.prototype,即Object构造函数的prototype属性。那么,Object.prototype对象有没有它的原型呢?回答是有的,就是没有任何属性和方法的null对象,而null对象没有自己的原型。

“原型链”的作用是,读取对象的某个属性时,JavaScript 引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined。

举例来说,如果让某个函数的prototype属性指向一个数组,就意味着该函数可以当作数组的构造函数,因为它生成的实例对象都可以通过prototype属性调用数组方法

var MyArray = function () {
};
//
MyArray.prototype = new Array();

var mine = new MyArray();
mine.push(1, 2, 3);
mine.length //

上面代码中,mine是构造函数MyArray的实例对象,由于MyArray的prototype属性指向一个数组实例,使得mine可以调用数组方法(这些方法定义在数组实例的prototype对象上面)。

原型链继承就是利用这个原理
将一个构造函数的原型指向另一个构造函数的实例对象来实现继承。

f

unction Box() {                            //Box构造
    this.name = 'Lee';
}
function Desk() {                            //Desk构造
    this.age = 100;
}
Desk.prototype = new Box();                    //Desc继承了Box,通过原型,形成链条
var desk = new Desk();
alert(desk.age);
alert(desk.name);                            //得到被继承的属性

混合继承
结合使用原型链与构造函数继承

function Box(age) {
    this.name = 'Lee'
    this.age = age;
}
Box.prototype.run = function () {               
        return this.name + this.age;
};
function Desk(age) {
    Box.call(this, age);      //构造函数继承继承了 name 和age 属性
}
Desk.prototype = new Box();        //原型链继承  run方法
var desk = new Desk(100);
alert(desk.run());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值