javascript有趣,有意思的js代码

谈谈js点击之后发生了什么

之所以突然想写这个文章,主要是之前看到一篇有意思的博文, 《探究点击事件在JavaScript事件循环中的表现》 ,有趣的地方在于JS点击事件加入回调的 并不是点击事件的回调方法 ,而是点击事件本身 (点击位置等描述点击的) 。

创新互联公司主营固安网站建设的网络公司,主营网站建设方案,App定制开发,固安h5微信小程序开发搭建,固安网站营销推广欢迎固安等地区企业咨询

当我们连续点击 button.a 两次的时候,结果却是

明明是点击的 button.a ,为什么会触发 button.b 的事件?

无论通过 onclick 还是 addEventListener 实现事件绑定,我怀疑绑定机制是一样的,因为在实际测试中,我发现 onclick 执行顺序和 addEventListener 是一样的,也就是什么时候绑定,那么就在第几个执行。

addEventListener 和 onclick 不同,不是直接给 dom 绑定属性,并且我在 dom 节点上也没有看到任何相应的对象用于保存事件,可见 addEventListener 是不同的机制,参考 EventEmitter ,试着去实现一个 addEventListener

通过上面分析,总结一下

求js大牛解惑!一个很有趣的问题: "0.14"*100 = 14.000000000000002 " , 而 0.13"*100 = 13;

这个问题挺复杂的,以前看过一次,但没太看懂,这次整理了一下。有兴趣的同学可以看看。

首先打印出0.14和0.14*100的二进制(程序见参考):

0.14 : 0 01111111100 0001111010111000010100011110101110000101000111101100

0.14*100 : 0 10000000010 1100000000000000000000000000000000000000000000000001

14.0 : 0 10000000010 1100000000000000000000000000000000000000000000000000

我们可以看到0.14的小数部分出现循环,就像10/3 = 1.33333…一样,所以0.14是有精度丢失的,

比较0.14*100和14.0,0.14*100多了最后一位1。

Java遵循IEEE 754标准来支持浮点数的操作,结合浮点值0.14,我们来看一下,1) 0.14的二进制格式

0 01111111100 0001111010111000010100011110101110000101000111101100.

根据IEEE 754标准,

注:S:符号(0正1负),E,指数,M小数部分。

对0.14格式化后的结果是:

S(1位) E(11位) M (52位)

0 01111111100 0001111010111000010100011110101110000101000111101100

根据计算公式:

我们可以得到e = 01111111100 – 1023 = 1020 – 1023 = -3

m = 1 (隐藏位) + 0.0001111010111000010100011110101110000101000111101100 = 1 +

Long.valueOf("0001111010111000010100011110101110000101000111101100", 2)/ (Math.pow(2, 52) – 1)

= 1.12000000000000013

n = 1.12000000000000013 *2^-3= 1.12000000000000013/8 约 0.14

接下来,第二个问题,2)为什么0.14 * 100 输出14.000000000000002?

由上可知0.14是不精确的,乘100只会扩大这个不精确度。具体的计算过程如下:

100的浮点二进制:

0 10000000101 1001000000000000000000000000000000000000000000000000

跟据浮点乘法规则指数相加,小数相乘,得到

0.14 * 100 =

2^(6-3) //100的指数是6,0.14的指数是-3

*

(1. 1001000000000000000000000000000000000000000000000000*

1. 0001111010111000010100011110101110000101000111101100) //小数部分

= 2^(6-3) * (1 + 0.1001000000000000000000000000000000000000000000000000 +

0.0001111010111000010100011110101110000101000111101100 +

0. 1001000000000000000000000000000000000000000000000000 * 0. 0001111010111000010100011110101110000101000111101100

//方便计算,分解乘数(同1.1 * 1.1 = 1 + 0.1 * 1 + 1 * 0.1 + 0.1*0.1)

这部分我用计算器计算,貌似精度丢失更严重,但可以得知小数部分依然是循环,而不能精确表达。同时,通过查看JDK中Double.toString(d)方法,我们可以看到SUN实现的浮点输出方法。所以最后打印在页面的是14.000000000000002而不是14.0.

故,浮点是用有限二进位接近表达一个数值,不精确是常态,使用要慎重

参考(强烈推荐)

IEEE 754 浮点数的表示精度探讨

解读IEEE标准754:浮点数表示

浮点乘法计算

打印DOUBLE二进制方法:

public class DoubleTest {

@Test

public void test(){

System.out.println("0.5 : " + this.dumpDouble(0.5));

System.out.println("0.14 : " + this.dumpDouble(0.14));

System.out.println("0.14*100 : " + this.dumpDouble(0.14 * 100));

System.out.println("14.0 : " + this.dumpDouble(14.0));

System.out.println("100 : " + this.dumpDouble(100));

Assert.assertEquals("100.0%", getPercentage(0.9999, 2));

Assert.assertEquals("100%", getPercentage(0.9999, 1));

Assert.assertEquals("99.9%", getPercentage(0.999, 2));

Assert.assertEquals("10.1%", getPercentage(0.101, 2));

Assert.assertEquals("10.2%", getPercentage(0.1015, 2));

Assert.assertEquals("11.0%", getPercentage(0.1095, 2));

Assert.assertEquals("0.11%", getPercentage(0.0011, 3));

final int TOTAL = 100000;

double[] data = new double[TOTAL];

for(int i = 0; i TOTAL; i++ ){

data[i] = Math.random();

}

//通过FORMAT,获得百分比,忽略精度

DecimalFormat f = new DecimalFormat("0.##'.0'%");

long start = System.currentTimeMillis();

for(int i = 0; i TOTAL; i++ ){

f.format(data[i]);

}

long end = System.currentTimeMillis();

System.out.println("0 time: " + (end - start));

//基于字符计算百分比

start = System.currentTimeMillis();

for(int i = 0; i TOTAL; i++ ){

this.getPercentage(data[i], 2);

}

end = System.currentTimeMillis();

System.out.println("1 time: " + (end - start));

}

public String dumpDouble(double d) {

StringBuilder b = new StringBuilder();

String bString = Long.toBinaryString(Double.doubleToLongBits(d));

int fillZeros = 64 - bString.length();

for(int i = 0; i fillZeros ; i++){

if(i == 1){

b.append(' ');

}

b.append('0');

}

for(int i = 0; i bString.length(); i++ ){

if((i + fillZeros) == 1 || (i + fillZeros) == 12){

b.append(' ');

}

b.append(bString.charAt(i));

}

return b.toString();

}

char[] next = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',};

public String getPercentage(double d, int precision){

StringBuilder b = new StringBuilder(Double.toString(d * 100));

int dot = b.indexOf(".");

if(dot 0 dot + precision b.length()){

char c = b.charAt(dot + precision);

//四舍五入

if(c '4'){

int j = dot + precision - 1;

if(j == dot) {

//跳过小数点

j --;

}

char n = next[b.charAt(j) - '0'];

b.setCharAt(j, n);

//向前进1

while(n == '0' j 0){

j --;

if(j == dot) {

//跳过小数点

j --;

}

//+1

n = next[b.charAt(j) - '0'];

b.setCharAt(j, n);

}

if(j == 0){

b.insert(0, 1);

dot++;

if(precision == 1){

b.setCharAt(dot, '%');

return b.substring(0, dot + 1);

}else{

b.setCharAt(dot + precision, '%');

return b.substring(0, dot + precision + 1);

}

}

}

b.setCharAt(dot + precision, '%');

return b.substring(0, dot + precision + 1);

}

b.append("%");

return b.toString();

}

JavaScript中的“面向对象”和Java语言中的“面向对象”有何不同?

面向对象三大特征:封装、继承、多态

基于封装,引出了js如何创建对象(class、function、原型+闭包创建私有变量等)。这个java和js都差不多

基于继承,引出了js继承的一些知识点,如extends、super、重写重载、abstract(typescript)、interface(typescript)。js主要是基于原型继承,而java主要是基于extends

多态存在的三个必要条件。重写(继承)、重载、向上转型:其中重写,js支持。重载js不支持,可以通过额外处理来支持向上转型,因为js是弱类型语言,不支持数据类型,ts支持(编译阶段)

也就是说对于多态的支持,目前js只支持一种。

总的来说 js的面向对象支持还没有java语言那么丰富严谨,正是因为这些宽松语法,也让js变得更加有趣。但是面向对象oop的思想是一致的。因为oop思想不是固定语言的特性,而是一种思想。随着js不断的更新迭代,相信其语法特性也更加丰富和严谨。

后话:js目前的发展趋势,好像不在跟随传统语言的oop,有点往函数式编程的路上转向

如何用javascript写碰壁反弹效果

碰壁反弹这个效果真的是挺有趣的,看起来就比较的高大上,而且写碰壁反弹成功后,也就能做些网页小游戏了。虽然这么说,但其实这个效果并不难写。只是坑比较的多,很多工作多年的程序员都可能会陷进去。

废话不多说,我们写起来:

1.CSS文件:

style

body{

border-style: solid;

border-color: sliver;

border-width: 5px;

margin-left: 100px;

width:1000px;

height:800px;

}

#screen{

width:800px;

height:600px;

background-color:#272822;

position:relative;

left:100px;

top:100px;

}

#egg{

width:50px;

height:50px;

background-color:red;

position:relative;

}

/style

2.body内容:

body

div id="screen"

div id="egg"

/div

/div

/body

3.JavaScript脚本:

var eggX=0;

var eggY=0;

var directX=1;

var directY=1;

function test(){

eggX+=directX;

eggY+=directY;

egg.style.left=eggX+"px";

egg.style.top=eggY+"px";

if(eggX+egg.offsetWidth=document.getElementById("screen").clientWidth||eggX=0) {

directX=-directX;

}

if(eggY+egg.offsetHeight=document.getElementById("screen").clientHeight||eggY=0){

directY=-directY;

}

}

setInterval("test()",1);

说明:拷贝代码,我们就能看到一个碰壁反弹的方框了。当然如果想要换成图片,直接将div里的内容换掉就OK了。不过这样似乎太美水准了点,在这附上完整代码(有障碍物的):

!DOCTYPE html

html

head

meta http-equiv="content-type" content="text/html; charset=UTF-8"

title碰壁反弹/title

style

body{

border-style: solid;

border-color: sliver;

border-width: 5px;

margin-left: 100px;

width:1000px;

height:800px;

}

#screen{

width:800px;

height:600px;

background-color:#272822;

position:relative;

left:100px;

top:100px;

}

#egg{

width:50px;

height:50px;

background-color:red;

position:relative;

}

#cock{

position:relative;

left:200px;

top:200px;

width:200px;

height:30px;

background-color: blue;

cursor: pointer;

}

/style

/head

body

div id="screen"

div id="egg"

/div

div id="cock" onmousedown="startDrag(this)" onmousemove="drag(this)" onmouseup="stopDrag(this)"

/div

/div

/body

script type="text/javascript"

var eggX=0;

var eggY=0;

var directX=1;

var directY=1;

function test(){

eggX+=directX;

eggY+=directY;

egg.style.left=eggX+"px";

egg.style.top=eggY+"px";

if(eggX+egg.offsetWidth=document.getElementById("screen").clientWidth||eggX=0) {

directX=-directX;

}

if(eggY+egg.offsetHeight=document.getElementById("screen").clientHeight||eggY=0){

directY=-directY;

}

if(eggY+egg.offsetHeight=document.getElementById("cock").offsetTop(eggX+egg.offsetWidth=200eggX+egg.offsetWidth=400)){

directY=-directY;

}

if((eggY-30)=document.getElementById("cock").offsetTop(eggX+egg.offsetWidth=200eggX+egg.offsetWidth=400)){

directY=-directY;

}

}

setInterval("test()",1);

/script

/html

现在JavaScript可以做哪些有趣的事

你好!

JavaScript的诞生首先就是网页脚本

之后的html api让JavaScript有了操作DOM和渲染DOM的能力,于是可以生成整个网页

苹果又加了料,在webkit component里加入了canvas /,于是js可以绘图

后来微软提出的的ajax和新的H5脚本诞生了SPA的概念,于是有了网页应用

我能画画,我能交互,我要成为高达!于是基于JavaScript的网页游戏如雨后春笋

Ryan Dahl这个人想搞点大事情,“要有服务器”,于是有了 NodeJS

希望我的回答能帮助你!

望采纳谢谢????

祝生活愉快!


分享文章:javascript有趣,有意思的js代码
当前网址:http://azwzsj.com/article/dscshgp.html