帖子
帖子
用户
博客
课程
显示全部楼层
19
帖子
0
勋章
294
Y币

从一个小程序看javascript,举一反三上手api

[复制链接]
发表于 2015-12-28 04:26:13
示例代码:
  1. <script type="text/javascript">
  2.    function disp(){
  3.    var now=new Date();
  4.    var year=now.getYear()+1900;
  5.    var month=now.getMonth()+1;
  6.    var qdate=now.getDate();
  7.    var day=now.getDay();
  8.    var arr_week= new Array("星期日","星期一","星期二","星期三","星期四","星期五","星期六");
  9.    var week=arr_week[day];
  10.    var timer="今年是"+year+"年"+month+"月"+qdate+"日"+week;
  11.    alert(timer);
  12.    }
  13.    </script>
复制代码
第一步:获取对象 var now=new Date();此为获取一个方法日期对象的值;
第二步:var year=now.getYear();获取的是Date()中的某个值;
第三步:自定义数组arr_week=new Array();这一步是建立一个数组;并且以day=now.getDay();的值作为arr_week的下标,day的值(单个int)依次对应了arr_week的值;

从这里我学习到了js中的定义变量、新建函数、基本的语言格式写法、简单的数组以及赋值、取值方法。

同是新手的以此共勉!举一反三,希望可以快速学会使用api.
19
帖子
0
勋章
294
Y币
通常一个构造函数是这样子的,它带有一个area的原型方法,在构造函数中传入长、宽并计算面积。

var Shape = function(width, height) {
    this.width = width;
    this.height = height;
};
Shape.prototype.area = function() {
    return this.width * this.height
};
var shape = new Shape(20, 30);
shape.area();
> 600

输出很完美,这也是经典JavaScript实现继承的方法,通过prototype添加对另外一个对象的引用。

不过一部分JavaScript程序是非常讨厌new关键字的,这个关键字有太浓烈的Java烙印了,而且掩盖了JavaScript基于原型的本质,降低了程序员使用JS语言的效率,因此你想把它省了,看看结果?

注* "JavaScript The Good Parts“的作者Douglas Crockford 曾写道  "A much better alternative is to not use new at all." (page 49),    参见另一程序员对AngularJS的吐嘈, 你已经毁了JavaScript(吐嘈之一就是里面到处都是new)

var shape = Shape(20, 30);
shape.area();
> TypeError: Cannot read property 'area' of undefined

道理再简单不过了,你只不过是执行了一个函数,但是这个函数并没有返回值,所以shape必然是undefined,看来new关键作用之一跟Java是一样的,就是实例化此对象并返回这个对象本身。所以你又试改写了一下函数:

var Shape = function(width, height) {
    var self = this;
    self.area = function() {
        return width * height;
    }
    return self;
};

var shape = Shape(20, 30);
shape.area();

> 600

不错,It works!也不用实例化Shape了,看上去一切正常,代码看上去更简单了,隐藏了不必要的属性,不过似乎你没有意识到你设计了一个潜在的更大的坑,尝试在console中打印这些:

area
> function () { return self.width * self.height; }

为什么are变成了全局变量?你不死心,又在window里打印
window.area
> function () {
        return width * height;
    }

结果还一样,其实这一现象在"Javascript: The Good Parts"一书中有很好的解析:

If you forget to include the new prefix when calling a constructor function, then this will not be bound to the new object. Sadly, this will be bound to the global object, so instead of augmenting your new object, you will be clobbering global variables. That is really bad. There is no compile warning, and there is no runtime warning. (page 49)

如果你在一个构造函数中忘了加new,那么这个新对象就不会绑定到新的实例上,不幸的是,它会绑定到全局对象上,你就会影响全局变量。这是非常糟糕的。没有编译警告,并且没有运行时的警告。(第49页)

看来在function函数内使用this绑定公开属性是非常危险的,因为你不确定会不会有人忘写了一个new,或者故意不加一个new,也许这就是为什么基于function的构造函数现在用得越来越少的原因吧,其实解决的办法非常简单,只需更改一处。

var Shape = function(width, height) {
    var self = {};
    self.area = function() {
        return width * height;
    }
    return self;
};

var shape = Shape(20, 30);
shape.area();
>600

其实还有很多其它的解决方案,还有一些开源项目甚至根本不使用构造函数,在此不再累述。
0
帖子
0
勋章
13
Y币
晕,现在难道不是21世纪吗?为嘛还19几几年?现在获得年份不是应该用getFullYear()吗?
8
帖子
0
勋章
1万+
Y币
感谢分享
3
帖子
0
勋章
309
Y币

感谢分享
76
帖子
2
勋章
219
Y币
mark一下,以后可能会用到!!
您需要登录后才可以回帖 登录

本版积分规则