JiM-W

keep Moving


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

jquery height innerHeight outerHeight

发表于 2016-04-17 | 分类于 jQuery

一 看解释:

1 height( )只可以获取内容高度,也就是原本设置的height高度值,或者由内容撑开的高度值

2 innerHeight( ) ,获取的高度包括 padding,不包括边框

3 outerHeight( ),获取的高度值包括 padding 和border ,不包括margin,

二 撸代码:

  • 不写参数可以获取当前值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<style>
*{
margin: 0;
padding: 0;
}
div{
border: 5px solid #000;
position: absolute;
width: 300px;
height: 200px;
margin: 100px;
}
p{
border: 1px solid green;
width: 200px;
height:18px
padding: 10px;
margin: 20px;
}
</style>
<div>
<p id="p2">这是一个段落</p>
</div>
<script src="jquery-1.12.2.js"></script>
<script>
console.log($("#p2").height()); //18 padding 18 margin 18
console.log($("#p2").innerHeight()); //18 38 38
console.log($("#p2").outerHeight()); //20 40 40
</script>

代码解释:padding 和 margin 逐渐加上之后,输出值变化如注释所示。

  • 写了参数可以设置 height(number) innerHeight(number) outerHeight(number) 它们各自代表的高度的值
  • 写了参数也可以这么设置 height(number+”px”) 栗子: $(“selector”).height(100+”px”);
  • Tips $(“selector”).width(number) 等价于 \$(“selector”).css(“width”,number);
1
2
3
4
5
6
7
8
9
10
<script>
$("#btn").click(function(){
$("#p2").height(30);
$("#p2").innerHeight(60);
$("#p2").outerHeight(70);
console.log($("#p2").height());
console.log($("#p2").innerHeight());
console.log($("#p2").outerHeight());
})
</script>

三:width( ) innerWidth( ) outerWidth( )也是一样的道理。

四:这些方法对隐藏元素和显示元素均有效。

五:如果获取的元素是一个节点列表,那么可以获取或者设置该列表元素的额第一个元素的宽高;

六 :window对象的尺寸

js 中有三种方法能够确定浏览器窗口的尺寸(浏览器的视口,不包括工具栏F12和滚动条)。

1
2
3
4
5
6
7
8
9
10
11
12
对于Internet Explorer、Chrome、Firefox、Opera 以及 Safari
- window.innerHeight - 浏览器窗口的内部高度
- window.innerWidth - 浏览器窗口的内部宽度
对于 Internet Explorer 8、7、6、5:
- document.documentElement.clientHeight
- document.documentElement.clientWidth
或者
- document.body.clientHeight
- document.body.clientWidth
//封装一个兼容各个浏览的代码
var height = window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight
var width = window.innerWidth || document.documentElement.clientWidth || docuemnt.body.clientWidth

jQuery中

1
$(window).height() $(window),width() ;

CMD command

发表于 2016-04-11 | 分类于 window

cmd常用命令行

1 IP地址

所谓IP地址就是给每个连接在互联网上的主机分配的一个32位地址。(就像每部手机能正常通话需要一个号码一样)

查看本机IP地址 ping、ipconfig、ifconfig(linux)

> ipconfig                       ... 显示信息
> ipconfig /all                  ... 显示详细信息
> ipconfig /renew                ... 更新所有适配器
> ipconfig /renew EL*            ... 更新所有名称以 EL 开头
                                     的连接
> ipconfig /release *Con*        ... 释放所有匹配的连接,
                                     例如“有线以太网连接 1”或
                                         “有线以太网连接 2”
> ipconfig /allcompartments      ... 显示有关所有隔离舱的
                                     信息
> ipconfig /allcompartments /all ... 显示有关所有隔离舱的
                                     详细信息

2、域名

由于IP地址基于数字,不方便记忆,于是便用域名来代替IP地址,域名是一个IP地址的“面具”

查看域名对应的IP地址 ping

3、DNS服务

DNS(Domain Name System)因特网上作为域名和IP地址相互映射的一个分布式数据库, 能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。

简单的说就是记录IP地址和域名之间对应关系的服务。

查找优先级 本机hosts文件、DNS服务器

ipconfig /flushdns 刷新DNS

4、端口

端口号是计算机与外界通讯交流的出口,每个端口对应不同的服务。

现实生活中,银行不同的窗口办理不同的业务。

查看端口占用情况 netstat -an

常见端口号 80、8080、3306、21、22

the Methods of String

发表于 2016-04-11 | 分类于 javascript

文本编辑命令

1 给元素设置contenteditable属性,可以设置该元素中的内容是否可以被编辑

1
<div contenteditable="true">click to rewrite</div>

2 给文档设置 design

javascript中的类型比较中的隐式转化是如何进行的?

发表于 2016-04-11 | 分类于 javascript

javascript中的类型比较中的隐式转化是如何进行的?

我们知道,在进行< > == 等比较运算的时候,总会遇到隐式转化,然后进行比较,有点混乱,这里简单总结下,方便参考:

在JavaScript中 对象到字符串 的转换经过如下步骤:
1) 如果对象具有toString()方法,则调用这个方法。如果返回一个原始值,JavaScript将这个值转换字符串,并返回这个字符串的结果。
2)如果对象没有toString()方法或者这个方法并不是返回一个原始值,那么JavaScript会调用valueOf()方法。如果存在这个方法,JavaScript调用它。如果返回值是原始值,将这个值转换为字符串,然后返回。
3)如果无法从toString()和valueOf()获得一个原始值,此时就会抛出一个类型错误。

在 对象到数字 的转换过程中,JavaScript做了同样的事情,只是它首先尝试调用valueOf()方法。
1)如果对象具有valueOf()方法,并返回一个原始值,则JavaScript将这个原始值转换为数字,并返回这个数字。
2) 否则,对象尝试去调用toString()方法,返回一个原始值,则JavaScript返回这个值。
3)如果无法从valueOf()和toString()获得一个原始值,此时就会抛出一个类型错误。

对象转换数字的细节解释了为什么空数组会被转换为数字0以及为什么具有单个元素的数组会被转换为一个数字。数组继承了默认的valueOf()方法,这个方法返回一个对象而不是一个原始值,因此数组到数组的转换调用toString()方法。空数组转换成空字符串,空字符串转换为数字0。含有一个元素的数组转换为字符串的结果和这个元素转换字符串的结果一样。如果数组只包含一个数字元素,这个数字转换为字符串,再转换为数字。

JavaScript中的”+”运算符可以进行数学加法和字符串连接操作。如果它的其中一个操作是对象,则JavaScript将使用特殊的方法将对象转换为原始值,而不是使用其它算术运算符的方法执行对象到数字的转换。”==”相等运算符与此类似。如果将对象和一个原始值比较,则转换将会遵照对象到原始值得转换方式进行。
“+”和”==”应用的对象到原始值得转换包含日期对象的一种特殊情形。日期类是JavaScript语言核心中唯一的预先定义类型,它定义了有意义的向字符串和数字类型的转换。对于所有非日期的对象来说,对象到原始值的转换基本上是对象到数字的转换(首先调用valueOf),日期对象则使用对象到字符串的转换模。然而这里的转换(+ ==)和上文讲述的并不完全一致:通过valueOf和toString 返回的原始值将被直接使用,而不会被强制转换为数字或者字符串。
和”==”一样,”<”运算符以及其它关系算术运算符也会做到对象到原始值得转换,但要除去日期对象的特殊情形:任何对象都会先尝试调用valueOf,然后调用toString。不管得到的原始值是否直接使用,它都不会进一步被转换为数字或字符串。

值 转换为字符串 数字 布尔值 对象
undefined “undefined” NaN false throws TypeError
null “null” 0 false throws TypeError
true “true” 1 true new Boolean(true)
false “false” 0 false new Boolean(false)
“” “” 0 false new String(“”)
“1.2” “1.2” 1.2 true new String(“1.2”)
“zero” “zero” NaN true new String(“zero”)
0 “0” 0 false new Number(0)
-0 “0” -0 false new Number(-0)
NaN “NaN” false new Number(NaN)
Infinity “Infinity” true new Number(Infinity)
-Infinity “-Infinity” true new Number(-Infinity)
1(无穷大,非零) “1” true new Number(1)
{}(任意对象) 对象本身 对象本身 true new Object({})
[](数组) “” 0 true new Array()
[0](数组) “0” 0 true new Array()
[0,1,2](数组) “0,1,2” NaN true new Array()
function(){} 函数本身 NaN true

javascript GC 垃圾回收机制

发表于 2016-04-11 | 分类于 javascript

Javascript 垃圾回收机制

1 当内存中的对象不再有引用的时候,那么过一段时间该对象开辟的内存空间则会回收

1
2
3
var obj = {"name":"Jhon"};
var obj = null ;
//当将obj设置为null 的时候,将会回收掉{"name":"Jhon"}
1
2
3
var obj = {"name":"JiM"};
var obj = {"age":18};
//当将obj的指向改变之后,原来的{"name":"JiM"},这块内存就会被回收

2 JavaScript垃圾回收的机制很简单:找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是时时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。

变量生命周期

什么叫不再使用的变量?不再使用的变量也就是生命周期结束的变量,当然只可能是局部变量 (函数体内用var声明的变量),全局变量的生命周期直至浏览器卸载页面才会结束。局部变量只在函数的执行过程中存在,而在这个过程中会为局部变量在栈或堆上分配相应的空间,以存储它们的值,然后再函数中使用这些变量,直至函数结束(闭包中由于内部函数的原因,外部函数并不能算是结束、

在局部作用域中,当函数执行完毕,垃圾回收机制很容易判断出,并且做出回收,但是全局变量声明时候需要释放内存空间则很难判断,因此我们在日常开发过程中,要尽量的避免使用全局变量,以确保性能。

在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。

全局变量什么时候需要自动释放内存空间则很难判断,因此在我们的开发中,需要尽量避免使用全局变量,以确保性能问题。

3 垃圾清除的方式

  • 标记清除(mark and sweep)

    这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。至于怎么标记有很多种方式,比如特殊位的反转、维护一个列表等,这些并不重要,重要的是使用什么策略,原则上讲不能够释放进入环境的变量所占的内存,它们随时可能会被调用的到。

    垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了,因为环境中的变量已经无法访问到这些变量了,然后垃圾回收器相会这些带有标记的变量机器所占空间。

  • 引用计数(reference counting)

    在低版本IE中经常会出现内存泄露,很多时候就是因为其采用引用计数方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值得引用次数减1,当这个值的引用次数变为0的时候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。

    看起来也不错的方式,为什么很少有浏览器采用,还会带来内存泄露问题呢?主要是因为这种方式没办法解决循环引用问题。比如对象A有一个属性指向对象B,而对象B也有有一个属性指向对象A,这样相互引用

    1
    2
    3
    4
    5
    6
    function test(){
    var a={};
    var b={};
    a.prop=b;
    b.prop=a;
    }

    这样a和b的引用次数都是2,即使在test()执行完成后,两个对象都已经离开环境,在标记清除的策略下是没有问题的,离开环境的就被清除,但是在引用计数策略下不行,因为这两个对象的引用次数仍然是2,不会变成0,所以其占用空间不会被清理,如果这个函数被多次调用,这样就会不断地有空间不会被回收,造成内存泄露。

    在IE中虽然JavaScript对象通过标记清除的方式进行垃圾回收,但BOM与DOM对象却是通过引用计数回收垃圾的,也就是说只要涉及BOM及DOM就会出现循环引用问题。看上面的例子,有同学回觉得太弱了,谁会做这样无聊的事情,其实我们是不是就在做

    1
    2
    3
    4
    window.onload=function outerFunction(){
    var obj = document.getElementById("element");
    obj.onclick=function innerFunction(){};
    };

    这段代码看起来没什么问题,但是obj引用了document.getElementById(“element”),而document.getElementById(“element”)的onclick方法会引用外部环境中德变量,自然也包括obj,是不是很隐蔽啊。

    解决办法

    最简单的方式就是自己手工解除循环引用,比如刚才的函数可以这样

    1
    2
    3
    4
    5
    window.onload=function outerFunction(){
    var obj = document.getElementById("element");
    obj.onclick=function innerFunction(){};
    obj=null;
    };

form

发表于 2016-04-11 | 分类于 javascript

form表单属性常用总结

1 enctype 设置或返回表单用来编码内容的 MIME 类型;规定在发送表单数据之前如何对其进行编码。

  • enctype 属性可设置或返回用于 编码表单内容 的 MIME 类型。如果表单没有 enctype 属性,那么当提交文本时的默认值是 “application/x-www-form-urlencoded”。
  • 当 input type 是 “file” 时,必须设置是 “multipart/form-data”。
  • 注意enctype属性是 用来设置如何对提交的内容进行编码的 属性
值 描述
application/x-www-form-urlencoded (默认) 在发送到服务器之前,所有字符都会进行编码(空格转换为 “+” 加号,特殊符号转换为 ASCII HEX 值)。
multipart/form-data 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
text/plain 空格转换为 “+” 加号,但不对特殊字符编码。如果设置该属性,这不会对上传数据进行编码

2 method 属性,规定表单以何种方式向服务器发送数据

​ 2.1 get方式发送数据 这时浏览器会与表单处理服务器建立连接,然后直接在一个传输步骤中发送所有的表单数据:浏览器会将数据直接附在表单的 action URL 之后。这两者之间用问号进行分隔。

如果不指定method属性值,默认以get方式发送数据

1
2
3
4
5
6
<form action="35-form.php" method="get">
<input type="text" name="username" value="txt"/>
<input type="password" name="psw" value="password"/>
<input type="submit" value="提交"/>
</form>
地址栏显示:http://127.0.0.1/03-ajxa/mycode/35-form.php?username=txt&psw=password

​ 2.2 post 方式发送数据 浏览器将会按照下面两步来发送数据。首先,浏览器将与 action 属性中指定的表单处理服务器建立联系,一旦建立连接之后,浏览器就会按分段传输的方法将数据发送给服务器。在服务器端,一旦 POST 样式的应用程序开始执行时,就应该从一个标志位置读取参数,而一旦读到参数,在应用程序能够使用这些表单值以前,必须对这些参数进行解码。用户特定的服务器会明确指定应用程序应该如何接受这些参数

1
2
3
4
5
6
<form action="35-form.php" method="post">
<input type="text" name="username" value="txt"/>
<input type="password" name="psw" value="password"/>
<input type="submit" value="提交"/>
</form>
地址栏显示:http://127.0.0.1/03-ajxa/mycode/35-form.php

hasOwnProperty和in的区别

发表于 2016-04-11 | 分类于 javascript

hasOwnProperty(“property”) 和 in 的区别

1 先看各自应用

1
2
3
4
5
6
7
8
9
10
11
12
<script>
function Test(){
this.foo= "bar";//将属性直接添加给将要实例化的对象
}
Test.prototype.name = "Jhon";//将属性值添加在原型上
var test1 = new Test();
// console.log(foo in test1);//语法错误,属性必须加上引号
console.log("foo" in test1);//true
console.log(test1.hasOwnProperty("foo"));//true
console.log("name" in test1);//true
console.log(test1.hasOwnProperty("name"));//false
</script>

2 “property” in obj 返回布尔类型,用于判断某个对象上是否有某个属性,包括其实例化的属性,以及原型链上的属性

obj.hasOwnProperty(“property”) 返回布尔类型,用于判断某个对象上是否有某个属性,但是仅仅指的是实例化的属性,不包括原型上的属性,也不包括属性指向一个对象当中的属性;

“property” in obj 可以判断一个对象是否有原生属性或者原型属性;

obj.hasOwnProperty(“property”) 只能判断原生属性,不能判断原型属性

注意属性一定要用引号括起来

3 我们可以进行一个封装,用来判断某个属性是否在原型上

1
2
3
4
5
6
7
8
9
10
11
12
function hasProperty (property,obj){
if(property in obj && !obj.hasOwnProperty(property)){
return true ;//该属性在原型上
}else{
return false;
}
}
//注意property传入字符串属性
var result1 = hasProperty("foo",test1);
console.log(result1);//false
var result2 = hasProperty("name",test1);
console.log(result2);//true

4 对于下面这种情况也要引起注意

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var obj = {
name:"Jhon",
age:13,
address:"American",
InnerObj:{
gender:"man"
}
}
console.dir(obj);
console.log( obj.hasOwnProperty("name"));//true
console.log("name" in obj); //true
console.log("gender" in obj); //fasle
//"gender"并不是实例化对象的属性,也不是在原型上的属性
console.log( obj.hasOwnProperty("gender"));//false

javascript中的运算符

发表于 2016-04-11 | 分类于 javascript

Javascript中运算符

1 一元运算符以及访问

. [] () 字段访问、数组下标、函数调用以及表达式分组
++ — - + ~ ! delete new typeof void 一元运算符、返回数据类型、对象创建、未定义值

delete可以删除对象的属性值以及方法,将其值为undefined,对于局部变量和方法,以及全局用var声明的变量,delete是没有用的;delete obj.prop ;

如果删除成功,delete x 返回true,否则返回false;

1
2
3
4
a = 6 ;
console.log(a);//6
console.log(delete a );//true
console.log(a);//报错
1
2
3
4
var a = 6 ;
console.log(a);//6
console.log(delete a );//fasle
console.log(a);//6
1
2
3
4
5
6
7
8
9
10
11
12
(function(){
// 'use strict' //如果在严格模式下会报错
var obj = {};
Object.defineProperty(obj,"name",{
value:"Jhon",
weitable:true,
configable:false,//控制属性是否可以被删除
enumerable:false
})
console.log(delete obj.name); //false
console.log(obj.name);//Jhon
})()

一元加法(+)和一元减法(-),对于数字来说,就是简单的加减,对于字符串来说,会将字符串转化为数字,类似于parseInt;

2 关系运算符 > >= < <= 返回一个布尔类型的值

(带有NaN的比较运算,返回的结果都是false)

2.1 基本数据类型的比较(比较的时候会将对象,数组等转化为原始值)

​ 2.1.1 Number类型比较 直接比较值即可 ,就是常规的算术比较,不做深究,

如果只有一个运算数是数字,那么会隐式的将另外一个运算数转化为数字,然后进行比较;字符串转化为数字,布尔类型转化为数字,对象转化为数字;

1
2
3
4
5
6
7
//如果有一个是数字类型的,会尽量将另外一个运算数也转化为数字类型
console.log(1 > []);//true 空数组转化为数字是0 ,先将空数组转化为空字符串,然后空字符串转化为 0
console.log(1 < []);//false
console.log(1 < {});//false 对象转化为字符串[object object] 然后转为数字是 NaN 带有NaN的关系运算表达式,返回的结果是false
console.log(1 < {});//false
console.log(1 < new Date());//true
console.log(1 > new Date());//false

​ 2.1.2 字符串类型比较 对于字符串,第一个字符串中每个字符的代码都与会第二个字符串中对应位置的字符的代码进行数值比较。完成这种比较操作后,返回一个 Boolean 值。

  • 大写字母的代码都小于小写字母的代码 ,所以,如果比较的字符有大写和小写,那么需要将字母字符串进行大小写转化
  • 如果两个运算数都是字符串,比较的是字符串中每一个字符的对应的字符代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
console.log("Ball"<"alpha");//true
console.log("Ball".toLocaleLowerCase()<"alpha".toLocaleLowerCase());//true
console.log('alpha' < "5");//false
console.log('alpha' > "5");//true
console.log("23" < "5");//true 对于字符串比较的是字符的编码
//"2" 的字符代码是 50,"3" 的字符代码是 51
console.log("" > "a");//false 字符串的比较是字符的编码
console.log("" < "a");//true
console.log("a" < []);//true
console.log("a" > []);//fasle
console.log("a" > {});//true 空对象经过ToPrimitive运算出来的是 '[object Object]' 字符串值,以 'a'.charCodeAt(0) 计算出的值是字符编码是97数字,而 '['.charCodeAt(0) 则是91数字,所以 'a' > ({}) 会是得到true。
console.log("a" < {});//fasle
console.log([1,2,3] < [1,2,4]) ;//true 数组的比较按照字典顺序比较
//接下来引出 数字和字符串的比较
console.log(23 < "5");//false

2.1.3 字符串和数字类型比较 会将字符串先转化成数字,将字符串转化成数字的时候,解析器会使用parseInt () parseFloat()将字符串转化为可比较的数字;

布尔类型值和数字类型值比较会将布尔类型转化为数字

2.1.4 复杂数据类型的比较

parseInt()

parseInt() 方法首先查看位置 0 处的字符,判断它是否是个有效数字;如果不是,该方法将返回 NaN,不再继续执行其他操作。但如果该字符是有效数字,该方法将查看位置 1 处的字符,进行同样的测试。这一过程将持续到发现非有效数字的字符为止,此时 parseInt() 将把该字符之前的字符串转换成数字。

例如,如果要把字符串 “12345red” 转换成整数,那么 parseInt() 将返回 12345,因为当它检查到字符 r 时,就会停止检测过程。

字符串中包含的数字字面量会被正确转换为数字,比如 “0xA” 会被正确转换为数字 10。不过,字符串 “22.5” 将被转换成 22,因为对于整数来说,小数点是无效字符。

parseFloat()

parseFloat() 方法与 parseInt() 方法的处理方式相似,从位置 0 开始查看每个字符,直到找到第一个非有效的字符为止,然后把该字符之前的字符串转换成整数。

不过,对于这个方法来说,第一个出现的小数点是有效字符。如果有两个小数点,第二个小数点将被看作无效的。parseFloat() 会把这个小数点之前的字符转换成数字。这意味着字符串 “11.22.33” 将被解析成 11.22。

1
2
3
4
//'alpha'转化成数字的时候,会直接返回NaN ,带有NaN的关系运算表达式,返回的结果是false
console.log('alpha' > 5);//false
console.log('alpha' < 5);//false
console.log("22.5" > 22); //true

2.2 == === != !== 比较运算

全等比较 === 不仅仅比较两个运算数的值,还比较两个运算数的数据类型,这个一般容易进行判断

对于 == 比较运算,会对运算数进行隐式转化,转化为原始值进行比较

如果我们要判断两个运算数是否相等的话,最好使用全等,因为 == != 会进行隐式类型转化;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1、如果两个值类型相同,进行 === 比较。 
2、如果两个值类型不同,他们可能相等。根据下面规则进行类型转换再比较: 
   a、如果一个是null、一个是undefined,那么[相等]。 
   b、如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。 
   c、如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 0 再比较。 
console.log([] == true);//fasle
console.log([] == false);//true
   d、如果一个是对象,另一个是数值就把对象转化为数字,另一个是字符串就把对象转化为字符串对象转换成基础类型,利用它的toString或者valueOf方法。js核心内置类,会尝试valueOf先于toString;例外的是Date,Date利用的是toString转换。非js核心的对象
   e、任何其他组合,都[不相等]。
1
2
console.log([] == ![]);//true 对于对象类型的比较,会发生隐式类型的转化,这里还要注意运算符的优先级 !比== 的优先级要高,所以 ![]为false,含有布尔类型的会转化为 false会转化为0 ,[]也会转化为0
console.log(![]);//false

3 + - 运算符

3.1 + 运算符 以下有两种情况(执行代码之前会将运算数转化为原始值)

+ 性运算符是字符串环境,会将数字,布尔类型,undefined NaN null 转化为字符串进行拼接

原始值: number string boolean null undefined 对象值[object,object]

3.1.1 : 如果两个 运算数都是数值类型,直接进行算术运算

3.1.2 : 如果有一个运算是不是数字,或者都不是数字,那么将会进行字符串拼接

  • 如果运算数有一个是字符串,那么这个运算环境就是字符串环境,需要将另外一个运算数转化为字符串,然后进行字符串的连接
    • 另外一个是字符串,直接进行拼接
    • 另外一个运算数是 数字 , 将数字转化字符串,然后进行字符串拼接
    • 另外一个运算数是 复杂数据类型 数组 或者对象 javascript会调用这两者的toString()方法,将它们转化为字符串,然后进行拼接
  • 如果两个运算数都是 数组 或者对象 ,那么在 + 性环境中,javascript会将两个运算数都转化成字符串,然后进行拼接;
  • 如果一个运算数是数字,为另外一个运算是是布尔类型,会将布尔类型转化为0或者1 ,然后进行数字运算
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//以下是第二种情况下,转化为字符串
var arr = [1,2,3]
var arr1 = [1,2,3,4]
var obj1 = {name:"Jhon"}
var obj2 = {name:"JiM"}
var num = 9;
var num1 = 6;
var str = "Jhon";
console.log(arr+num);//1,2,39
console.log(typeof (arr+num));//string
console.log(arr+str);//1,2,3Jhon
console.log(typeof (arr+str));//string
console.log(obj1+num);//[object Object]9
console.log(arr1+arr);//1,2,3,41,2,3
console.log(obj1+obj2);//[object Object][object Object]
console.log("3"+NaN);//NaN
console.log('str'+undefined);//strundefined
console.log('str'+null);//strnull
//----------
console.log(undefined+NaN);//NaN
console.log(1+NaN);//NaN
console.log(null+NaN);//NaN
//-----如果有一个运算数是对象,那么javascript会调用toString转化为字符串,在和NaN记性字符串的拼接
console.log([]+NaN); //NaN(这个是字符串NaN)
console.log({}+NaN);//[object Object]NaN
console.log(1 + [] + 1 );//11 string类型的
//-------------------
console.log(true + 1);//2
console.log(true + '3');//true3

3.2 - 运算符 两种情况 -性运算符的环境是数字环境,会将字符串,布尔类型等转化为数字进行运算

3.2.1 如果两个运算数都是数字,那么进行基本的算术运算;

3.2.2 如果有一个运算数是数字,另外一个运算数是字符串 ,那么会尝试将字符串转化为数字 ,如果转化失败,则返回NaN

3.2.3 如果一个运算数是布尔类型,一个运算数是数字,会将布尔类型转化为数字

1
2
3
4
5
6
7
8
9
10
11
console.log(num - num1);//3
//只要有一个不是数字,运算结果就返回NaN
console.log(num - arr);//NaN
console.log(num - str);//NaN
console.log(arr1-arr);//NaN
console.log(obj1-obj2);//NaN
//---------------------------------------
console.log(true - 3);//-2
console.log(true - '3');//-2
console.log('2'-'1');//1
console.log('str'-'1');//NaN

4 逻辑运算符  !  &&  || 根本要明白布尔类型转化的规则,这个逻辑运算也就清楚了   

1
2
3
4
5
6
7
//-------------------! 运算符 以下结果全部返回true
console.log(!undefined);
console.log(!null);
console.log(!NaN);
console.log(!0);
console.log(!"");
// ! 运算返回的一定是布尔类型的
1
2
3
4
5
6
7
8
9
//----------------|| 或运算符 返回布尔类型或者其他数据类型
console.log(''|| null);//null 空字符串 和null都是false 返回第二个运算数
console.log(2||1);//2 2转化为布尔类型是true,直接返回,不在及逆行第二个运算数的运算
console.log(2||null);//2
//简单来说,或运算就是找true的运算,找到true则马上返回该运算数;
//1 对于运算数已经声明的情况
// 如果第一个运算数是true,那么就返回第一个运算数,不再进行第二个运算数的判断
// 如果第一个运算数是false,那么就直接返回第二个运算数,无论第二个运算数是true还是false;
//2 对于运算数没有声明的情况,如果第一个运算数没有声明,则直接报错,如果第二个运算数没有声明,在第一个运算数为true的情况下不会报错,如果第一个运算数为false,会报错
1
2
3
4
5
6
7
8
9
//----------------&& 与运算符
console.log('' && null); //如果第一个运算数为false,则直接返回第一个运算数
console.log(2 && 1 ); //如果第一个运算数为true,则直接返回第二个运算数
console.log(2 && null );
//简单来说 ,与运算就是找false的运算,找到false则马上返回该运算数;
//1 对于已经声明的变量,
// 如果第一个运算数是false,则直接返回第一个运算数,不再进行第二个运算数的判断,
//如果第一个运算数是true,则直接返回第二个运算数,无论第二个运算数是true还是false;
//2 对于运算数没有声明的情况,如果第一个运算数没有声明,那么直接报错,如果第二个运算数没有声明,在第一个运算数为false的情况下不会报错,当第一个运算数为true的时候,会报错
1
2
console.log(notDefined || true );//对于没有定义的直接报错是这样的情况,不再一一举证
console.log("cant be excuted");

5 类型转换

5.1 转化为布尔类型为 false 的值如下;这个是逻辑运算的核心支撑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 0 null undefined NaN "" (空字符串) 返回false
console.log(Boolean(null));
console.log(Boolean(undefined));
console.log(Boolean(0));
console.log(Boolean(""));
console.log(Boolean(NaN));
console.log(Boolean(false));
//对于非空字符串 数字 数组 对象 返回true
console.log(Boolean("str"));
console.log(Boolean(9));
console.log(Boolean(new Object));
//if( ) 会进行隐式类型转化 if判断会对flag进行隐式类型转化,转化为布尔类型的值
document.getElementById(id)如果能够获取某个元素,那么返回该元素对象,如果获取不到,返回undefined
获取到的话,返回一个对象,对象的布尔类型值是 true

###

7 条件运算符 variable = boolean expression ? true value : false value ;

在进行条件运算符运算的时候,会对boolean expression进行转化为布尔类型,需要熟悉了解布尔类型转化的规则;

8 赋值运算符,返回 = 右边的运算数,从右向左进行运算;

1
2
3
4
5
6
7
8
9
10
var x = 5 ;
console.log(x = 7);//7
var y = "str";
console.log(x = y );//str
//"链式"赋值运算符----------------------------------
var arr, num1,num2 ;
arr = [num1,num2] = [1,2,3,4];
console.log(arr);// [1,2,3,4]
console.log(num1);//1
console.log(num2);//2

js乱炖

发表于 2016-04-11 | 分类于 javascript

1 逗号操作符:返回最后一个操作数,逗号运算符会先执行左侧表达式,然后执行右侧表达式然后执行右侧表达式并且以右侧表达式的计算结果作为返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// Note that the following creates globals and is disallowed in strict mode.
a = b = 3, c = 4; // Returns 4 in console
console.log(a); // 3 (left-most)
console.log(a = b = 3, c = 4);//3 4
console.log((a = b = 3, c = 4));//4
x = (y = 5, z = 6); // Returns 6 in console
console.log(x); // 6 (right-most)
//------------------------------------
x = (y = 5, z = 6,z=5); // Returns 6 in console
console.log(x); // 5 (right-most)
//-----------------------------------
function myFunc() {
var x = 0;
return (x += 1, x); // the same as return ++x;
}
console.log(myFunc());//1
//--------------------------------------
var x = 20;
var temp = {
x: 40,
foo: function() {
var x = 10;
return this.x;
}
};
var res = (temp.foo, temp.foo)(); // 20,而不是40
console.log(res);//20
var res = ( 1,temp.foo)(); // 20,而不是40
console.log(res);//20

2 常用hack技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
* png24位的图片在iE6浏览器上出现背景,解决方案是做成PNG8.
* 浏览器默认的margin和padding不同。解决方案是加一个全局的*{margin:0;padding:0;}来统一。
* IE6双边距bug:块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大。
浮动ie产生的双倍距离 #box{ float:left; width:10px; margin:0 0 0 100px;}
这种情况之下IE会产生20px的距离,解决方案是在float的标签样式控制中加入 ——_display:inline;将其转化为行内属性。(_这个符号只有ie6会识别)
渐进识别的方式,从总体中逐渐排除局部。
首先,巧妙的使用“\9”这一标记,将IE游览器从所有情况中分离出来。
接着,再次使用“+”将IE8和IE7、IE6分离开来,这样IE8已经独立识别。
css
.bb{
background-color:red;/*所有识别*/
background-color:#00deff\9; /*IE6、7、8识别*/
+background-color:#a200ff;/*IE6、7识别*/
_background-color:#1e0bd1;/*IE6识别*/
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
* IE下,可以使用获取常规属性的方法来获取自定义属性,
也可以使用getAttribute()获取自定义属性;
Firefox下,只能使用getAttribute()获取自定义属性。
解决方法:统一通过getAttribute()获取自定义属性。
* IE下,even对象有x,y属性,但是没有pageX,pageY属性;
Firefox下,event对象有pageX,pageY属性,但是没有x,y属性。
* 解决方法:(条件注释)缺点是在IE浏览器下可能会增加额外的HTTP请求数。
* Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示,
可通过加入 CSS 属性 -webkit-text-size-adjust: none; 解决。
超链接访问过后hover样式就不出现了 被点击访问过的超链接样式不在具有hover和active了解决方法是改变CSS属性的排列顺序:
L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}

3 其他小结

  • CSS里的visibility属性有个collapse属性值是干嘛用的?在不同浏览器下以后什么区别?

    对于普通元素visibility:collapse;会将元素完全隐藏,不占据页面布局空间,与display:none;表现相同.
    如果目标元素为table,visibility:collapse;将table隐藏,但是会占据页面布局空间.
    仅在Firefox下起作用,IE会显示元素,Chrome会将元素隐藏,但是占据空间.

  • position跟display、margin collapse、overflow、float这些特性相互叠加后会怎么样?

    如果元素的display为none,那么元素不被渲染,position,float不起作用,如果元素拥有position:absolute;或者position:fixed;属性那么元素将为绝对定位,float不起作用.如果元素float属性不是none,元素会脱离文档流,根据float属性值来显示.有浮动,绝对定位,inline-block属性的元素,margin不会和垂直方向上的其他元素margin折叠.

  • 对BFC规范(块级格式化上下文:block formatting context)的理解?

    (W3C CSS 2.1 规范中的一个概念,它是一个独立容器,决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。)
    一个页面是由很多个 Box 组成的,元素的类型和 display 属性,决定了这个 Box 的类型。
    不同类型的 Box,会参与不同的 Formatting Context(决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染,也就是说BFC内部的元素和外部的元素不会互相影响

    请解释一下为什么需要清除浮动?清除浮动的方式

    清除浮动是为了清除使用浮动元素产生的影响。浮动的元素,高度会塌陷,而高度的塌陷使我们页面后面的布局不能正常显示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1、父级div定义height;
2、父级div 也一起浮动;
3、常规的使用一个class;
.clearfix:before, .clearfix:after {
content: " ";
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix {
*zoom: 1;
}
4、SASS编译的时候,浮动元素的父级div定义伪类:after
&:after,&:before{
content: " ";
visibility: hidden;
display: block;
height: 0;
clear: both;
}
解析原理:
1) display:block 使生成的元素以块级元素显示,占满剩余空间;
2) height:0 避免生成内容破坏原有布局的高度。
3) visibility:hidden 使生成的内容不可见,并允许可能被生成内容盖住的内容可以进行点击和交互;
4)通过 content:"."生成内容作为最后一个元素,至于content里面是点还是其他都是可以的,例如oocss里面就有经典的 content:".",有些版本可能content 里面内容为空,一丝冰凉是不推荐这样做的,firefox直到7.0 content:”" 仍然会产生额外的空隙;
5)zoom:1 触发IE hasLayout。
通过分析发现,除了clear:both用来闭合浮动的,其他代码无非都是为了隐藏掉content生成的内容
  • CSS优化、提高性能的方法有哪些?
1
2
3
4
关键选择器(key selector)。选择器的最后面的部分为关键选择器(即用来匹配目标元素的部分);
如果规则拥有 ID 选择器作为其关键选择器,则不要为规则增加标签。过滤掉无关的规则(这样样式系统就不会浪费时间去匹配它们了);
提取项目的通用公有样式,增强可复用性,按模块编写组件;增强项目的协同开发性、可维护性和可扩展性;
使用预处理工具或构建工具(gulp对css进行语法检查、自动补前缀、打包压缩、自动优雅降级);
  • 浏览器是怎样解析CSS选择器的?
    1
    2
    样式系统从关键选择器开始匹配,然后左移查找规则选择器的祖先元素。
    只要选择器的子树一直在工作,样式系统就会持续左移,直到和规则匹配,或者是因为不匹配而放弃该规则。
  • ::before 和 :after中双冒号和单冒号 有什么区别?解释一下这2个伪元素的作用。
1
2
3
4
5
6
7
8
单冒号(:)用于CSS3伪类,双冒号(::)用于CSS3伪元素。(伪元素由双冒号和伪元素名称组成)
双冒号是在当前规范中引入的,用于区分伪类和伪元素。不过浏览器需要同时支持旧的已经存在的伪元素写法,
比如:first-line、:first-letter、:before、:after等,
而新的在CSS3中引入的伪元素则不允许再支持旧的单冒号的写法。
想让插入的内容出现在其它内容前,使用::before,否者,使用::after;
在代码顺序上,::after生成的内容也比::before生成的内容靠后。
如果按堆栈视角,::after生成的内容会在::before生成的内容之上
  • BFC(Block formatting context)直译为”块级格式化上下文”。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。

  BFC布局规则:

  1. 内部的Box会在垂直方向,一个接一个地放置。
  2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
  3. 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  4. BFC的区域不会与float box重叠。
  5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  6. 计算BFC的高度时,浮动元素也参与计算

哪些元素会生成BFC:

  1. 根元素
  2. float属性不为none
  3. position为absolute或fixed
  4. display为inline-block, table-cell, table-caption, flex, inline-flex
  5. overflow不为visible
  • 如果需要手动写动画,你认为最小时间间隔是多久,为什么?(阿里)
1
多数显示器默认频率是60Hz,即1秒刷新60次,所以理论上最小间隔为1/60*1000ms = 16.7ms
  • 什么是CSS 预处理器 / 后处理器?
1
2
3
4
5
- 预处理器例如:LESS、Sass、Stylus,用来预编译Sass或less,增强了css代码的复用性,
还有层级、mixin、变量、循环、函数等,具有很方便的UI组件模块化开发能力,极大的提高工作效率。
- 后处理器例如:PostCSS,通常被视为在完成的样式表中根据CSS规范处理CSS,让其更有效;目前最常做的
是给CSS属性添加浏览器私有前缀,实现跨浏览器兼容性的问题。
  • 说几条写JavaScript的基本规范?
1
2
3
4
5
6
7
8
9
1.不要在同一行声明多个变量。
2.请使用 ===/!==来比较true/false或者数值
3.使用对象字面量替代new Array这种形式
4.不要使用全局函数。
5.Switch语句必须带有default分支
6.函数不应该有时候有返回值,有时候没有返回值。
7.For循环必须使用大括号
8.If语句必须使用大括号
9.for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染。

prototype 浅析

发表于 2016-04-11 | 分类于 javascript

js中 构造函数prototype属性 实例化对象 proto 属性 以及原型链的总结

1 注意区分

  • prototype是构造函数的属性,可以直接操作,所有的实例化对象可以共享由其创建的属性或者方法,也就数说,当函数被new调用的时候,实例化的对象上才有原型上的属性,但是不用new,而直接调用的时候,却没有;

  • proto 是实例化对象的属性,该属性是JS对象上的隐藏属性,这个属性指向的是该对象 对应构造函数的prototype属性;该属性不可实际操作;

  • 实例化的对象里面包括 实例化的属性 + proto 属性 ,

    proto 属性里面又包含constructor 属性和 proto (原型链终点)

1.1 test.prototype.property = “value”; test.prototype.property =function(){ };直接向原型中添加属性,

1
2
3
4
5
function test(){
this.age = 13 ;
}
var obj = new test;
console.log(obj);

图1

1
2
3
4
5
6
7
8
9
10
11
12
function test(){
this.age = 13 ;
}
var obj1 = new test;
obj1.name = "JiM";//点操作符,直接给当前实例化的对象添加属性或者方法,只能给obj1 添加
test.prototype.name = "Jhon";//构造函数的prototype属性可以直接将属性和方法添加到__proto__:属性里面,所有的由该构造函数实例化的对象都会拥有由prototype声明的属性和方法,
var obj2 = new test ;
//注意 prototype属于构造函数的属性,而不是实例化对象的属性
console.log(obj1);
console.log(obj2);

图2

1
2
3
console.log(obj1.name);//JiM
console.log(obj2.name);//Jhon
//原型链的对象会遵循就近原则进行取值

构造函数首字母一般要大写,这里由于开始的疏忽,暂时用小写

1.2 test.prototype = new test2 ( ) ;改变实例对象的proto原型指向;

1
2
3
4
5
6
7
8
9
10
function test(){
this.age = 13 ;
}
function test2(){
this.email = "gmail";
}
//注意 prototype属于构造函数的属性,而不是实例化对象的属性
test.prototype = new test2();//
var obj2 = new test ;
console.log(obj2);

1.3 所有的函数的 proto 指向 构造函数 Function.prototype ;

​ 所有实例对象的 proto 指向 对应构造函数的 prototype属性: arr. proto === Array.prototype

​ 所有构造函数的prototype属性中有一个constructor属性,指向其构造函数

​ 在Javascript中每个函数都有一个prototype属性和 proto  属性,

  • 其中所有函数 的 proto 属性指向Function的 prototype属性,
  • 所有实例化对象 的 proto 属性指向其对应 的构造函数的 prototype 属性;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
function MyFunc(){}
console.dir(Function);
console.dir(Object);
console.dir(Array);
console.dir(MyFunc);
console.dir(Function.__proto__ === Function.prototype);//true
console.dir(MyFunc.__proto__ === Function.prototype);//true
console.dir(Array.__proto__ === Function.prototype);//true
//所有函数,包括(Object,Array,Date ,MyFunc 这些构造函数),它们的__proto__属性指向Function构造函数的prototype属性,即 Function.prototype
var myFunc = new MyFunc ;
var arr = new Array();
console.dir(myFunc);
console.dir(arr);
console.log(myFunc.__proto__ === MyFunc.prototype);//true
console.log(arr.__proto__ === Array.prototype);//true
//所有实例化的对象,对象,对象的__proto__属性指向其对应的构造函数的prototype属性
</script>

1.4 注意区分函数也是对象,但是对象不一定是函数;Function是所有函数的构造函数,包括内置构造函数(内置对象,如果给Function的prototype添加了属性,那么所有通过构造函数new出来的对象都会在 proto 属性中有该属性)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script>
function fn(){ //声明一个函数
}
fn.address = "China"; //如果将函数看成一个对象的话,点操作符可以给函数添加属性
//当把函数当成构造函数使用的 时候,生成的实例化的对象里面的属性,只有通过构造函数原型添加的属性和方法,以及在构造函数内部声明的属性和方法
fn.prototype.na = "Jhon";
fn.prototype.age = 15 ;
Function.prototype.foo = "bar";//通过函数的构造函数Function的prototype添加属性
console.dir(fn);//查看fn的属性组成
//如果将fn看成对象的话,fn里面有如下属性 address prototype __proto__ 属性等
console.log(fn.foo);//bar
console.log(Array.foo);//bar
console.log(fn.na);//undefined //. 操作符只会顺着原型属性__proto__往上去找某个属性
console.log(fn.__proto__.na);//undefined
console.log(fn.prototype.na);//Jhon
console.log(fn.age);//undefined
console.log(fn.__proto__.age);//undefined
console.log(fn.prototype.age);//15
//要区分函数的prototype属性和__proto__属性
//函数的__proto__属性指向Function构造函数的prototype属性,即 Function.prototype
console.log(fn.address);//China
</script>

1.5 有点绕

  • 所有的函数都有prototype属性,同时也都有 proto 属性,该属性指向Function构造函数的prototype属性;Function的 proto 属性指向Object构造函数,函数也是对象;
  • 所有的对象都有 proto 属性,指向该对象的构造函数的prototype属性

2 原型继承,所谓的继承,其实就是一个构造函数原型指向另外一个构造函数的实例化对象

2.1 原型继承的所有的属性由 所有 的实例化的对象共享,一个改变,其余的都会改变,这是原形继承的一个缺点;

2.2 原型的继承方式:借助构造函数继承、组合继承

2.3 原型继承要注意理解复杂类型传递的是数据在堆内存中的地址;

2.4.1 不使用prototype属性定义的对象方法,是静态方法,只能直接用类名进行调用!另外,此静态方法中无法使用this变量来调用对象其他的属性!  

2.4.2 使用prototype属性定义的对象方法,是非静态方法,只有在实例化后才能使用!其方法内部可以this来引用对象自身中的其他属性!

1…161718…20
JiM-W

JiM-W

keep fighting!

195 日志
52 分类
90 标签
© 2017 JiM-W
由 Hexo 强力驱动
主题 - NexT.Pisces