整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

JavaScript 中undefined与null

JavaScript 中undefined与null的区别分析
null==undefined; // true
null !==undefined; // true

ull

首先他是一个对象,但是是一个空对象,因为是一个对象,所以

typeof null; // "object"

null是js保留的关键字;

null在参与数值运算的时候将自动转换成 0 ;例如:

var c=123 + null; // 123
var a=188 * null; // 0

null表示"没有对象",即该处不应该有值。典型用法是:

(1) 作为函数的参数,表示该函数的参数不是对象。

(2) 作为对象原型链的终点。

Object.getPrototypeOf(Object.prototype) // null

undefined

首先undefined是全局对象中的一个特殊属性,他的值是一个未定义的,我们来看看他是否为全局对象的属性:

alert("undefined" in window);

上述这段代码会在浏览器输出true;

然而当我们创建一个空对象的时候:

var anObj={}; 
alert('undefined' in anObj); //输出:false 

undefined参与的所有数值运算,其值都会返回 NaN

var h=123+undefined; // NaN

undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:

(1)变量被声明了,但没有赋值时,就等于undefined。

(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。

(3)对象没有赋值的属性,该属性的值为undefined。

(4)函数没有返回值时,默认返回undefined。

当我们在程序中使用undefined值时,实际上使用的是window对象的undefined属性。

同样,当我们定义一个变量但未赋予其初始值,例如:

var vaule ; // undefined
这个时候JavaScript预编译会将其初始值的设置为 window.undefined 的引用。

于是,当我们将一个变量或值与undefined比较时,实际上是与window对象的undefined属性比较。这个比较过程中,JavaScript会搜索window对象名叫‘undefined'的属性,然后再比较两个操作数的引用指针是否相同。

由于window对象的属性值是非常多的,在每一次与undefined的比较中,搜索window对象的undefined属性都会花费时 间。在需要频繁与undefined进行比较的函数中,这可能会是一个性能问题点。因此,在这种情况下,我们可以自行定义一个局部的undefined变 量,来加快对undefined的比较速度。例如:

function anyFunc() { 
 var undefined; //自定义局部undefined变量 
 if(x==undefined){
 console.log(undefined)
 } //作用域上的引用比较 
 
 while(y !=undefined){
 console.log(undefined)
 } //作用域上的引用比较 
}; 

其中,定义undefined局部变量时,其初始值会是对window.undefined属性值的引用。新定义的局部undefined变 量存在与该函数的作用域上。在随后的比较操作中,JavaScript代码的书写方式没有任何的改变,但比较速度却很快。因为作用域上的变量数量会远远少 于window对象的属性,搜索变量的速度会极大提高。

这就是许多前端JS框架为什么常常要自己定义一个局部undefined变量的原因!

avaScript 中的数据类型可分为两类:基本数据类型(也称为原始数据类型)和复杂数据类型(也称为引用数据类型)。具体而言,JavaScript 支持以下数据类型:

基本数据类型(Primitive Types)

1,字符串类型(String)

  • 字符串是文本的数据类型,使用单引号(')或双引号(")括起来表示。
  • JavaScript中的字符串是不可变的,即一旦创建,就不能改变其值(虽然可以改变字符串变量的值,使其指向另一个字符串)。
  • 字符串中的每个字符都有一个索引,索引从0开始。
  • ES6引入了模版字符串(template strings),使用反引号(`)括起来,可以嵌入变量和表达式。

2,数值类型(Number)

  • 数值类型用于表示数字,包括整数和浮点数。
  • JavaScript中的数字均采用IEEE 754标准定义的64位浮点格式表示,但在某些情况下(如数组索引)会基于32位整数处理。
  • 数值类型可以表示极大或极小的数字,超出范围的数字会表示为Infinity(正无穷)或-Infinity(负无穷)。
  • 特殊值NaN(Not-a-Number)用于表示某些非数值的操作结果。

3,布尔类型(Boolean)

  • 布尔类型只有两个值:true和false,用于表示逻辑上的真和假。

4,未定义类型(Undefined)

  • 当声明了一个变量但没有给它赋值时,它的值就是undefined。
  • undefined是JavaScript中的一个预定义的全局变量,表示“缺少值”。

5,空类型(Null)

  • null表示一个空值,是一个只有一个值的特殊类型。
  • 从逻辑上看,null表示一个空对象的指针,这也是为什么使用typeof检测null时结果为"object"的原因。

6,Symbol类型(ES6新增)

  • Symbol是一种原始数据类型,用于创建唯一的标识符。
  • Symbol类型的值可以作为对象的属性名,以避免命名冲突。
  • Symbol可以通过Symbol()函数或Symbol.for()函数创建,后者创建的Symbol是全局的,可以重复获取。

7,BigInt类型(较新,ES2020引入)

  • 用于表示大于2^53 - 1的整数。BigInt提供了一种方法来表示任意大小的整数。
  • 任意精度:BigInt可以表示任意精度的整数,解决了之前JavaScript中Number类型整数溢出的问题。
  • 不可变性:BigInt的值是不可变的,即一旦创建,其值就不能被改变。
  • 与Number的区别:BigInt与Number类型不是严格相等的,它们之间不能直接进行算术运算,除非先将它们转换为同一类型。

复杂数据类型(Reference Types)

  1. 对象类型(Object)对象是一种复杂的数据类型,用于存储键值对集合。JavaScript中的数组、函数、日期等都是对象的一种特殊形式。对象属性名可以是字符串或Symbol类型。
  2. 数组类型(Array)数组是一种特殊的对象,用于存储一系列有序的值。数组的每个值称为元素,可以通过索引访问。数组索引从0开始,可以是整数或字符串(但通常使用整数)。
  3. 函数类型(Function)函数是JavaScript中的一等公民,可以作为变量赋值、作为参数传递、也可以作为返回值。函数用于定义可重复使用的代码块,可以接收参数并返回结果。
  4. 其他特殊对象类型 如正则表达式(RegExp)、日期(Date)等,它们都是基于对象类型的特殊构造器创建的。

总结

JavaScript 数据类型多种多样,涵盖了七种基本数据类型(字符串、数值、布尔、未定义、空、Symbol、BigInt)以及多种复杂数据 Object 类型(对象、数组、函数等)。掌握这些数据类型的特点和应用方法,对于编写高效、可维护的 JavaScript 代码具有重要意义。

TML5之fileReader异步读取文件及文件切片读取

fileReader的方法与事件

fileReade实现图片预加载

fileReade实现文件读取进度条

fileReade的与file.s实现文件切片读取

一、fileReader的方法与事件

1.方法

FileReader.abort():终止读取操作。返回时, readyState属性为DONE。

FileReader.readAsArrayBuffer():将文件读取为ArrayBuffer数据对象。

FileReader.readAsBinaryString():将文件读取为二进制数据。

FileReader.readAsDataURL():将文件读取为DataURL编码(base64)==>URL格式的字符串。

FileReader.readAsText():将文件读取为文本==》字符串表示的文件内容。

2.事件

FileReader.onloadstart:读取开始时触发

FileReader.onprogress:读取中

FileReader.onloadend:读取完成触发, 无论成功或失败

FileReader.onload:文件读取成功完成时触发

FileReader.onabort:中断时触发

FileReader.onerror:出错时触发

3.实现图片读取预览

在Web FileReader API接口实现之前, 图片预览的通常做法是先将图片上传至服务器, 上传成功以后通过过触发ajax请求到刚刚上传的图片, 然后加载到页面。这个过程中如果图片选择错误或者需要修改上传的图片, 就需要重复上传和下载请求, 并且还需要在服务器替换图片资源, 会浪费大量的网络资源和服务器资源。现在通过FileReader实现本地图片读取预览, 就可以在本地实现图片修改, 节省服务器资源。

既然是HTML5的API就目前来说肯定存在兼容性问题, 目前IE10开始支持FileReader, 所以通过服务上传下载的图片预览方式还是有必要的, 接下来的示例仅仅展示FileReader的图片读取预览代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
.imgBox{
display: flex;
width: 300px;
height: 300px;
border: 1px solid #300;
justify-content: center;
align-items: center;
}
</style>
</head>
<body>
<input type="file" name="">
<div class="imgBox"></div>
</body>
<script>
var imgBox=document.getElementsByClassName('imgBox')[0];
var reader=new FileReader(); //创建文件读取对象
var inp=document.getElementsByTagName('input')[0]; //获取文件源
inp.onchange=function(){ //input域发生改变后触发文件读取
reader.readAsDataURL(inp.files[0]); //使用文件读取对象读取图片为base64编码
}
reader.onload=function(e){ //当图片读取成功后触发
var img=new Image(); //创建img对象
img.src=e.target.result; //给img对象添加缓存中的bese64位编码的图片数据(异步)
img.onload=function(e){ //图片数据加载完成以后
if(this.width > this.height){ //当图片的宽度大于高度
img.style.width='100%'; //是:设置图片宽度100%,实现图片全部预览
}else{
img.style.height='100%';//否:设置图片高度100%,实现图片全部预览
}
imgBox.style.backgroundColor='#000';
imgBox.innerHTML=null;
imgBox.appendChild(img);
}
}
</script>
</html>

4.实现文件加载进度条

在FileReader.onprogress事件对象中有两个属性loaded和total, loaded表示当前文件读取大小, total表示文件整体大小, 并且在读取时会持续触发更新最新读取状态的数据,

根据FileReader.onprogress事件就可以实现文件加载进度条的动画效果了, 但是由于FileReader是h5的API在IE中最低兼容到10版本, 所以需要根据具体的项目和兼容性来设计交互。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
.progress{
position: relative;
margin-top: 5px;
width: 300px;
height: 20px;
border: 1px solid #300;
}
.progressText{
display: inline-block;
position: absolute;
width: 300px;
height: 20px;
text-align: center;
font-size: 10px;
line-height: 20px;
}
.progressSpan{
display: inline-block;
/* width: 200px; */
height: 20px;
background-color: #f0f;
}
</style>
</head>
<body>
<input type="file" name="">
<!-- 文件加载进度条 -->
<div class="progress">
<span class="progressText"></span>
<span class="progressSpan"></span>
</div>
</body>
<script>
//获取文件源(所有功能实现的公共代码区)
var inp=document.getElementsByTagName('input')[0]; //获取文件源
var reader=new FileReader(); //创建文件读取对象
// fileReader实现图片加载进度条
var progressSpanObj=document.getElementsByClassName('progressSpan')[0];
var progressTextObj=document.getElementsByClassName('progressText')[0];
inp.onchange=function(){
reader.readAsArrayBuffer(inp.files[0]);
}
reader.onloadstart=function(e){ //开始读取文件时触发
progressTextObj.innerText="正在读取文件(0%)...";
}
reader.onprogress=function(e){ //读取进度事件
console.log(Math.round(e.loaded / e.total * 100));
var precent=Math.round(e.loaded / e.total * 100);
progressSpanObj.style.width=precent / 100 * 300 + 'px';
progressTextObj.innerText='正在读取文件(' + precent + '%)...';
}
reader.onload=function(e){
progressTextObj.innerText='文件读取完成(100%)';
}
reader.onerror=function(e){
progressTextObj.innerText="文件读取出错误(~0v0~)";
}
</script>
</html>

二、fileReade的与file.slice实现文件切片读取

通过input-type[file]获取的文件对象上有这样几个数据:

inputDom.files[0];//获取File对象(在onchange事件后获取)

File对象上的属性与方法:

File():构造函数,返回一个新的文件对象

File.lastModified:返回所引用文件最后的修改日期,为自 1970年1月1日0:00 以来的毫秒数。没有已知的最后修改时间则会返回当前时间。

File.lastModifiedDate:返回当前File对象所引用文件最后修改事件的Date都西昂。

File.name:返回当前File对象所引用文件的名字。

File.size:返回文件的大小

File.webkitRelativePath:返回Filex相关的path或URL(这是个非标准属性, chrome上获取的是一个空字符串)

File.slice():文件对象上本身是没有方法的,slice方法同通过继承Blob对象上的slice方法实现的。

File对象说明手册(MDN):https://developer.mozilla.org/zh-CN/docs/Web/API/File

File.slice()方法说明手册(MDN):https://developer.mozilla.org/zh-CN/docs/Web/API/Blob/slice