js学习

前言

平时的项目中,很少再去写原生的js代码,自己也很少再去思考某些代码在原生情况的书写方法,导致自己忽略了很多原生js中重要的内容。学习其他框架的时候也是只会使用,而对实现原理了解的较少。最近因为某些契机,燃起了巩固js知识的欲望,故分享下最近学习的一些心得体会。


1、数据类型

  1. 基本数据类型:number,string,boolean,undefined,null
  2. 复杂数据类型:object
    一些相关的内容:
    1. n/a not applicable
    2. 加法无法进行类型转换,减法可以,+/-0相加减,同号得正,异号得负。
    3. NaN not a number
    4. undefined表示一个特殊的值undefined
    5. null表示一个空指针
    6. 前置递增或递减会在求值以前执行,称为副效应
    7. 禁止给undefined、NaN、Infinity赋值
    5+"5"="55"  string
    5-"5"=0  number
   -0-(+0)=-0
   
// true
    typeof(null);//object
    null==null;
    null===null   
    null==undefined;
    undefined==undefined;
    undefined===undefined;
// false
    NaN==NaN;

2、数组

数组的一些常用方法:

  • 栈方法(LIFO): pop、push
  • 队列方法(FIFO): shift、unshift
  • 排序 sort、reverse
    要使数组元素按大小排序可在排序方法中加入函数,如从小到大排序:
    var arr=[5,2,8];
    arr.sort(function(a,b){
        return a-b;
    });
  • 数组相加: concat
  • 迭代方法:
    数组的迭代方法不会修改数组。
    1. every() 数组中的每一项都运行给定函数 全为true就是true 否则为false
    2. filter() 数组中的每一项都运行给定函数 返回结果为true的函数
    3. forEach() 数组中的每一项都运行给定函数 (IE9+)
    4. some()对数组中的每一项运行给定函数,如果该函数对任一项返回 true,则返回 true。
    5. map()对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
      具体的实例代码如下:
var numbers=[1,2,3,4,5,5,6,7,8,2,43];
var every=numbers.every(function(item,index,array){
	return item>2;
});
console.log(every);    //false
var filter =numbers.filter(function(item,index){
	return item==index;
});
console.log(filter);  //[5,6,7,8]

var foreach=numbers.forEach(function(item,index){
	item+=1;
});
console.log(foreach);   //undefined
var some=numbers.some(function(item,index){
	return item>index+50;
});
console.log('some='+some);  //some=false

var map=numbers.map(function(item,index){
	return item*2;
});
console.log(map);    //[2, 4, 6, 8, 10, 10, 12, 14, 16, 4, 86]

var sum=numbers.reduce(function(prev,next,index){
	return prev+next;
});
console.log(sum);  //86

3、DOM

文档对象模型(document object model),这是一个api,描绘了一个层次化的节点树,用于增加,删除,修改页面的某一部分。DOM有level1,level2,level3三级,DOM事件有0级,2级,以及三级事件。

  • 获取子节点:childNodes
  • 获取父节点:parentNode
  • 兄弟节点:previousSibiling(前面)、nextSibling(后面)
  • 获取当前URL:URL
  • 获取来源URL:referrer

获取元素的一些方法:

  • 文档元素表示<html> 也是页面的根元素
  • 通过ID获取,标签名获取
  • anchors 返回对文档中所有anchor对象的引用,如
 <a href="#" onclick="change()" id="test" name="test">test</a>
 <script>
    console.log(document.anchors);
    //[a#test, test: a#test]
    //length:1
 </script>
  • 获取页面所有表单元素: forms
  • 获取页面所有图片元素:images
  • 获取页面所有链接元素:links
  • 获取元素的标签名:tagName
  • 元素的属性:getAttribute,setAttribute,removeAttribute、createAttribute (不支持IE6)
  • 创建元素:createElement
  • nodeType,nodeName,nodeValue
节点类型 nodeType nodeName nodeValue
element 1 元素名 null
attr 2 属性名 属性值
text 3 #text 节点内容
comment 8 #comment 注释文本
document 9 #document null

DOM的扩展

  1. querySelector()/querySelectorAll()
  2. html5新增dom方法
    1. getElementsByClassName
    2. htmlDocument:readyState有两种状态 loading以及complete
    3. 自定义数据属性 data-
  3. 获取内容 innerHTML,outerHTML
  4. IE8以下不支持事件流(事件冒泡,事件捕获)。javascirpt与HTML之间的交互是通过事件实现的。IE的事件流叫做事件冒泡,即事件开始时由最具体的元素逐级向上传播至不具体的元素。如下:
<body onclick="bodyClick()">
    test1
    <a href="#" onclick="change()" id="test" name="test">test</a>
</body>
<script>
    function bodyClick(){
	alert(1);
}
function change(){
	alert(0);
}
</script>

点击a链接的结果是,先弹出0,再弹出1。
事件捕获则是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。


4、BOM

浏览器对象模型(browser object model),提供了很多对象,用于访问浏览器的功能,核心是window,它是浏览器的一个实例。

  • 打开关闭窗口: open/close
  • 系统对话框:alert/confirm/prompt
  • 打印:print
  • 获取窗口位置: window.screenLeft/Top 表示窗口相对于屏幕的位置
  • 窗口移动:moveTo/moveBy
  • 窗口大小:resizeTo/resizeBy
  • 打开原始窗口对象:openr
  • 前进后退:history.go()/back()/forward()

5、创建对象

对象的定义:无序属性的集合,函数也是对象。
a. 工厂模式,用函数来封装以特定接口创建对象的细节。如下:

function factory(name,number,score){
	var o=new Object();
	o.name=name;
	o.number=number;
	o.score=score;
	return o;
}
var obj = new factory('leo',1,60);

b.构造函数。创建一个新对象,将构造函数的作用域赋给新对象(this),执行构造函数中的代码,最后返回新对象。如下:

function Student(name,number,score){
	this.name=name;
	this.number=number;
	this.score=score;
	this.outPut=function(){
		console.log('name:'+this.name+'
number:'+this.number+'
score:'+score);
	}
}
var yu=new Student('monkey',1001,99);

构造函数始终都应该以大写字母开头.

c.原型模式。所有的函数都有一个原型(prototype)属性,通过将信息添加到原型对象中去,让所有新建的对象实例共享这些信息。

function Person(){

}

Person.prototype.name='300kuai';
Person.prototype.number=38;
Person.prototype.score=59;
Person.prototype.outPut=function(){
	console.log('name:'+this.name+'
number:'+this.number+'
score:'+this.score);
}

var person1=new Person();

d.自定义类型。组合使用构造函数模式和原型模式。构造函数用于定义实例属性,原型用于定义方法和共享属性。这也是使用最多的一种方法。

  • 对象的遍历:
    1.for-in。
var obj={'first':'leo','second':'monkey'};
for (var prop in obj) {	
	console.log(
		obj[prop]
	);
}

6、函数

  1. 函数声明提升,即执行代码之前会先读取函数声明。如以下代码是正确的。
console.log(sumFunc(10,10));
function sumFunc(){
	var sum=0;
	for( var i in arguments){
		sum+=arguments[i];
	}
	return sum;
}

但是,如果将函数赋给变量,函数没有函数名,是匿名函数,必须先赋值。如下面代码就是错误的:

console.log(sumFunc(10,10));
var sumFunc=function(){
	var sum=0;
	for( var i in arguments){
		sum+=arguments[i];
	}
	return sum;
}

总结

从事前端工作越久,使用的框架,方案越多,越发现,其实最基础的还是最重要的。不管框架多么酷炫,实现的功能多么强大,始终只是我们编程的一种工具。当然,虽然这些工具不是不可或缺的,但是,掌握这些框架知识对我们项目模块化的开发,软件性能的提高确实起到了重要的作用。

又看了一遍最基础的javascirpt,对于原型,闭包,继承的理解还是不是非常深刻,接下去的几天也打算重点看下这些内容,下一篇文章也应该是这几个内容。

原文地址:https://www.cnblogs.com/monkeyleo/p/5834015.html