ES6

ES6基础

1、let

1、let声明的变量只能在当前块级作用域内有效
2、let声明的变量不能被重复声明
3、不存在变量提升
4、暂存死区

let monkey = '美猴王';
{
	console.log(monkey);   //暂存死区
	let monkey = '孙悟空';
}
console.log(monkey);

块级作用域
通俗的讲,就是一对花括号中的区域{ … },且块级作用域可以嵌套
1、if( ) { }
2、switch( ) { }
3、fort( ) { }
4、try{ } catch( err ) { }
5、{ }

案例:生成四个按钮 每一个按钮点击的时候弹出1-10
使用var定义i

		var i=0;
		for(i=1; i<=0; i++){
			(function(i){
				var btn = document.createElement('button');
				btn.innerText = i;
				btn.onclick = function(){
					alert(i);
				};
				document.body.appendChild(btn);
			}(i)
		}

使用let定义i

		for(let i=1; i<=0; i++){
			var btn = document.createElement('button');
			btn.innerText = i;
			btn.onclick = function(){
				alert(i);
			};
			document.body.appendChild(btn);
		}

2、const

声明一个常量 — 不可改变的量
const a = 1;
常量必须在声明的时候赋值
否则会报错:Missing initializer in const declaration
const的特性:
1、常量声明后不能被修改
2、不能重复声明
3、不存在变量提升
4、只在当前块级作用域内有效
5、常量为引用类型时,可以修改该引用类型
修改的时候指向的地址不能改变

const xiaoming = {
	age: 14,
	name: '小明'
}
console.log(xiaoming);
xiaoming.age = 22;
xiaoming
console.log(xiaoming);  //修改成功
xiaoming = {};  //修改失败

可以通过Object.freeze( )方法阻止常量为引用类型时候的修改

const xiaoming = {
	age: 14,
	name: '小明'
}
Object.freeze(xiaoming);
console.log(xiaoming);
xiaoming.age = 22;
xiaoming.dd = 14;  //修改失败
xiaoming
console.log(xiaoming);  //修改失败
xiaoming = {};  //修改失败

es6之前如何定义常量

	//1. 假装是常量
	var base_color = '#ff00ee';
	//2. Object.defineProperty();
	var cst = {a = 1};
	Object.defineProperty(cst, 'a', {
		value: 'xiaoming',
		writable: false
	});
	//Object.seal()阻止对象添加属性或对象
	Object.seal(cst);

自己封装一个freeze方法

	//自己封装一个freeze方法
	Object.defineProperty(Object, 'freezePolyfill', {
		value: function(obj){
			for(var i in obj){
				if(obj.hasOwnProperty){
					Object.defineProperty(obj, i, {
						writable: false
					});
				}
			}
			Object.seal(obj);
		}
	});

3、解构赋值


//数组的解构赋值
// let [a,b,c] = [1,2,3];
// let [a,b,c] = [,123,];
// let [a=111,b,c] = [,222,];
// let [a=111,b,c=333] = [,222,444];
// console.log(a,b,c);		
		

//对象的解构赋值
// let {foo,bar} = {foo: 'hello', bar: 'hi'};
// let {foo,bar} = {bar: 'hi', foo: 'hello'};
// console.log(foo, bar);
// 给对象属性添加别名(如果有了别名,原名就无效了)
// let {foo:abc,bar} = {bar: 'hi', foo: 'nihao'};
// console.log(abc, bar);
		

// 对象的解构赋值指定默认值
let {foo:abc="world",bar} = {bar: 'hi'};
console.log(abc, bar);

let {cos,sin,random} = Math;
console.log(cos);
console.log(sin);
console.log(random);


//字符串的解构赋值
let [a,b,c,d,e] = "hello";
// let [a,b,c,d,e,length] = "hello";
console.log(a,b,c,d,e);
// console.log(length);
console.log("hello".length);

// let {length} = "hinihao";
// console.log(length);

4、字符串扩展

/*
	字符串扩展
	includes():判断字符创中是否包含指定的字符串(有true,无false)
				参数一:匹配的字符串
				参数二:从第几个字符开始匹配
	startsWith():判断2字符串是否以特定的字串开始
	endsWith():判断2字符串是否以特定的字串结束

	模板字符串
 */ 
console.log('hello world'.includes('world',6));
console.log('hello world'.includes('world',8));

let url = 'admin/index.php';
console.log(url.startsWith('admin'));
console.log(url.startsWith('aadmin'));
console.log(url.endsWith('php'));
console.log(url.endsWith('phph'));

//----------------------------------------------
let obj = {
	username: 'list',
	age: '13',
	gender: 'male'
}
let tag = '<div><span>'+obj.username+'</span><span>'+obj.age+'</span><span>'+obj.gender+'</span></div>';
console.log(tag);

//反引号表示模板,模板中的内容可以有格式,通过${}方式填充数据
let fn = function(info){
	return info;
}
let tpl = `
	<div>
		<span>${obj.username}</span>
		<span>${obj.age}</span>
		<span>${obj.gender}</span>
		<span>${1+1}</span>
		<span>${fn('hello world')}</span>
	</div>
`;
console.log(tpl);


5、函数扩展

/*
	函数扩展
	1、参数默认值
	2、参数解构赋值
	3、rest参数 (剩余参数)
	4、...扩展运算符
 */

//	1、参数默认值
function foo1(param){
	let p = param || 'hello';
	console.log(p);
}
foo1();
foo1('hi');

function foo2(param = 'hillo'){
	console.log(param);
}
foo2();
foo2('hello world');

//-------------------------------
//	未解构赋值
// function foo(name='list', age=15){
// 	console.log(name,age);
// }
// foo();
// foo('zhangsan', 25);

//	2、参数解构赋值
function foo3({name='list', age=15} = {}){
	console.log(name,age);
}
foo3();
foo3({name: 'zhangsan', age:25});

//---------------------------------
//	3、rest参数 (剩余参数)
function foo4(a,b, ...param){
	console.log(a,b);
	console.log(param);
}
foo4(0, 55, 1, 21, 31, 64, 0);

//----------------------------------
//	4、...扩展运算符 
function foo5(a,b,c,d,e,f){
	console.log(a+b+c+d+e+f);
}
foo5(1,2,3,4,5,7);
let arr = [1,2,3,4,5,6];
foo5.apply(null, arr);
foo5(...arr);

//-----------------------------------
//合并数组
let arr1 = [1,2,3];
let arr2 = [4,5,6];
let arr3 = [...arr1, ...arr2];
let arr4 =  [0,0,0];
arr4 = arr4.concat(arr1,arr2,arr3);
console.log(arr3);
console.log(arr4);

6、剪头函数


/*
	箭头函数
 */
function foo1(){
	console.log('hello');
}
foo1();

let foo2= () => console.log('hello');
foo2();
//---------------------------------------
function foo3(v){
	return v;
}
let foo4 = v => v;
console.log(foo3(111));
console.log(foo4(111));
//----------------------------------------
//多个参数需要小括号包住
let foo5 = (a,b) => {let c=1; console.log(a+b+c);}
foo5(10,4);

let arr = [111, 222, 333, 444, 555];
arr.forEach(function(element, index){
	console.log(index, element);
});
arr.forEach((element, index)=>{
	console.log(index, element);
})

//剪头函数的注意事项
//1、箭头函数中this取决于函数的定义,而不是调用
let foo00 = (a,b) => {
	console.log(this);  //为空对象:{}
}
foo00(1,2);

function foo01(){
	//使用call调用foo时,这里的this其实是call的第一个参数
	// console.log(this);
	setTimeout(()=>{
		console.log(this.num);
	},1000);
}
foo01();
foo01.call({num:110});

//2、箭头函数不可以new
let foo02 = () => {this.num = 123;}
//new foo02();

//3、箭头函数不可以使用arguments获取参数列表,可以使用rest参数代替
let foo03 = (a,b,c) => {
	console.log(a,b,c);
	// console.log(arguments);
}

foo03(111,222,333);
let foo04 = (...param) =>{
	console.log(param[1]); //222,param确定为一个数组对象
	console.log(param);
}
foo04(111,222,333,444,555);


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计中的实现,以及它们在MATLAB环境中的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用中颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述中提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least SquaresESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法中,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用中,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值