DAY27-ES6基础

 

 

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

这段代码创建了一个变量 `i` 并将其赋值为 `0`,然后使用 `for` 循环结构,从 `1` 到 `10` ,遍历 `i` 的取值,并使用一个立即执行函数,将遍历到的当前值 `i` 传递作为参数。

在这个立即执行函数中,创建了一个 `button` 元素,设置它的文本内容为 `i`,并为该按钮设置了一个 `onclick` 事件监听器,当用户点击该按钮时,弹出一个弹窗,展示当前的 `i` 值。最后,将 `button` 元素添加到了 `body` 元素中。

值得注意的是,由于 JavaScript 的作用域是基于函数的而非基于块级作用域的,该立即执行函数的作用域中的 `i` 与循环中的 `i` 并不是同一个变量,使得每个按钮事件监听器都能按照预期正确地展示相应的 `i` 值。

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

为什么这里加上let和不加let结果一样?

`let` 定义变量在代码块中拥有块级作用域的特性,可以更好地隔离变量,防止变量名污染和变量重复定义的问题。但如果在代码块中未发生变量重新定义、变量与外部环境变量名不冲突等情况时,使用 `let` 和 `var` 声明变量结果可能是相同的。

需要注意的是,`let` 与 `var` 声明变量的一个主要区别是,`var` 声明的变量在同一作用域内可以被多次定义或重新赋值,而 `let` 声明的变量则只能被定义一次,之后只能重新赋值,这也是 JavaScript 在最新标准中引入 `let` 的目的之一。


为什么const引用类型的时候可能被修改?


const obj = {name: 'Tom', age: 18};  // 使用 const 声明一个对象
console.log(obj);   // 输出 {name: 'Tom', age: 18}

obj.age = 20;   // 使用改变属性的方式来修改对象的值
console.log(obj);   // 输出 {name: 'Tom', age: 20}

```

我们使用 `const` 声明了一个名为 `obj` 的对象。调用 `console.log(obj)` 以输出 `{name: 'Tom', age: 18}`,这是这个对象的初始值。之后我们使用 `obj.age = 20`更改了对象属性 age 值,然后再次调用 `console.log(obj)`输出 `{name: 'Tom', age: 20}`,这个对象的属性已经被成功地更改了。

值得注意的是,虽然 `obj` 是通过 `const` 关键字声明的,但是这仅仅意味着 `obj` 的引用不允许被重新赋值,而并不是不允许更改它所指向对象的属性。如果需要创建一个不可变的对象,可以使用一些类似 `Object.freeze()`的内置函数来达到目的。

// const ARR = [];
// Object.freeze(ARR);
// ARR.push(1);
// console.log(ARR);
Object.defineProperty(Object, 'freezePolyfill', {
  value: function(obj) {
    var i;
    for (i in obj) {
      if (obj.hasOwnProperty(i)) {
        Object.defineProperty(obj, i, {
          writable: false
        });
      }
    }
    Object.seal(obj);
  }
});

这段代码定义了一个名为 `freezePolyfill` 的方法,使用 `Object` 对象的 `defineProperty` 函数,将传递进来的 `obj` 对象的所有属性配置为只读,从而实现了对象的冻结。

具体而言,`freezePolyfill` 的实现会遍历传递进来的对象,为其所有的具有自身属性的属性设置只读 `writable: false` 属性,然后使用 `Object.seal` 函数将对象密封,阻止向对象添加新属性,并可以将已有属性的配置更改为不可变。

需要注意的是,该方法为一个 polyfill 函数,也就是将 `Object.freeze()` 函数的实现引入了可能不支持该函数的浏览器环境中。尽管这可以在一些情况下达到一定的兼容效果,但在代码使用时应谨慎,避免因修改过多环境内置函数而导致的副作用。

 数组的解构赋值

let [a, b, c] = [1, 2, 3];
console.log(a); // 输出 1
console.log(b); // 输出 2
console.log(c); // 输出 3
```

在这个例子中,我们定义了一个包含三个元素的数组 `[1, 2, 3]`,然后使用解构赋值的语法将 `[1, 2, 3]` 的值的分别赋值给变量 `a`、`b` 和 `c`。

在解构赋值中,等号左边的变量名要和等号右边的数组元素对应,即:第一个元素对应第一个变量,第二个元素对应第二个变量,以此类推。如果右侧的数组元素不够时,未被对应到的变量将被赋值为 `undefined`。同时,如果右侧的元素多于左侧的变量数,则会忽略多余的元素。

let a = 1, b = 2;
[a, b] = [b, a];
console.log(a); // 输出 2
console.log(b); // 输出 1

在这段代码中,我们首先声明了两个变量 `a` 和 `b`,并分别赋值为 `1` 和 `2`。然后,我们使用解构赋值的语法将两个变量的值互换,这样变量 `a` 的值变为 `2`,变量 `b` 的值变为 `1`。


解构赋值语法的使用可以让我们编写更加优雅和简洁的代码,并且提高了代码的可读性。

对象的解构:

const person = {
  name: 'Tom',
  age: 18,
  gender: 'male'
};

const { name, age, gender } = person;

console.log(name);   // 输出 'Tom'
console.log(age);    // 输出 18
console.log(gender); // 输出 'male'

在这个例子中,我们定义了一个名为 `person` 的对象,它包含三个属性 `name`、`age` 和 `gender`。然后,我们使用解构赋值的方式快速地从 `person` 中提取这三个属性,并将它们赋值给变量 `name`、`age` 和 `gender`。最后,输出这三个变量的值。
需要注意的是,在对象解构赋值时,左侧是一个对象字面量,右侧是一个与左侧对象属性名相同的对象,采用的是类似“名值对”一样的方式进行一一匹配和赋值。这意味着左侧的变量名应该和右侧的对象属性相对应,而且左右两侧变量名需要为一致。

对象解构赋值同样可以嵌套使用,可以通过对嵌套对象进行解构,快速方便地获取其内部嵌套的属性值。

 const player = {
nickname: '感情的戏∫我没演技∆',
master: '东海龙王',
skill: [{
		skillName: '龙吟',
	mp: '100',
	time: 6000
 	},{
 		skillName: '龙卷雨击',
		mp: '400',
		time: 3000
 	},{
		skillName: '龙腾',
	mp: '900',
		time: 60000
	}]
};

const { nickname } = player;
 const { master } = player;
 const { skill: [ skill1, { skillName }, { skillName: sklName } ] } = player;
const { skill } = player;
 const [ skill1 ] = skill;

这段代码是使用JavaScript语言编写的,并定义了一个名为`player`的对象。对象拥有四个属性,分别是昵称(nickname)、主人公(master)和技能(skill)。
`const { nickname } = player;`这行代码使用了解构赋值语法,从`player`对象中提取了`nickname`属性,并将其赋值给变量`nickname`。

`const { master } = player;`同样使用了解构赋值语法,从`player`对象中提取了`master`属性,并将其赋值给变量`master`。

`const { skill: [skill1, { skillName }, { skillName: sklName } ] } = player;`这行代码同样使用了解构赋值语法,从`player`对象中提取了`skill`属性,并将其赋值给了一个新的对象,该对象包含了三个属性,分别是`skill1`、`skillName`和`sklName`。其中`skill1`表示`skill`数组中的第一个元素;`{ skillName }`表示从`skill`数组中的第二个元素中提取了`skillName`属性,将其赋值给变量`skillName`;`{ skillName: sklName}`表示从`skill`数组中的第三个元素中提取了`skillName`属性,并将其赋值给变量`sklName`。

`const [ skill1 ] = skill;`这行代码同样使用了解构赋值语法,从`skill`数组中提取了第一个元素,将其赋值给变量`skill1`。

 

// 如何对已经申明了的变量进行对象的解构赋值

let age;
 const obj = {
name: '小明',
 	age: 22
};

 ({ age } = obj);

这段代码是使用JavaScript语言编写的,并定义了两个变量,分别是`age`和`obj`。

`let age;`定义了一个变量`age`,但未对其进行赋值,因此此时`age`的值为`undefined`。

`const obj = { name: '小明', age: 22 };`定义了一个对象`obj`,包含两个属性`name`和`age`,分别对应字符串`'小明'`和数字`22`。

`({ age } = obj);`这行代码使用了解构赋值语法,从`obj`对象中提取了`age`属性,并将其赋值给变量`age`。这里使用了圆括号(`()`)是因为在JavaScript中,如果直接使用`age = obj.age`的方式将`age`赋值为`obj`对象中的`age`属性值时,语法上会出现错误;所以需要将整个语句放在一对圆括号中,以表示这是一个解构赋值语句。

总的来说,这段代码的作用是将对象`obj`中的`age`属性值提取出来,并赋值给变量`age`。最终的结果是变量`age`的值为`22`。

let girlfriend = {
name: '小红',
	age: undefined,
};

 let { name, age = 24, hobby = ['学习'] } = girlfriend;

`let { name, age = 24, hobby = [ '学习' ] } = girlfriend;`这行代码使用了解构赋值语法,从`girlfriend`对象中提取了`name`属性,并将其赋值给变量`name`;提取了`age`属性,将其赋值给变量`age`,如果`age`的值为`undefined`,则会将其默认值设为`24`;提取了`hobby`属性,将其赋值给变量`hobby`,如果`hobby`不存在,则会将其默认值设为一个包含字符串`'学习'`的数组`[ '学习' ]`。

总的来说,这段代码的作用是将对象`girlfriend`中的`name`和`age`属性值提取出来,并将其分别赋值给变量`name`和`age`。如果`age`属性的值为`undefined`,则将`age`默认设为`24`。最终的结果是变量`name`的值为`'小红'`,变量`age`的值为`24`,变量`hobby`的值为`[ '学习' ]`。

 const { name, hobby: [ hobby1 ], hobby } = {
	name: '小红',
	hobby: ['学习']
 };

这段代码是对一个对象进行解构赋值,并将其属性分别赋值给变量。对象的属性包括name和hobby。

在解构赋值时,使用了ES6中的对象解构特性,通过花括号包裹需要解构的属性名,同时使用":"操作符将hobby解构成单独的数组"hobby1",并将原"hobby"的值以普通变量"hobby"的形式赋值。

解构赋值过程中,变量name接收了对象属性name的值,变量hobby1接收了值为"学习"的数组的第一个元素,变量hobby则接收了整个数组作为它的值。

最终,变量name的值为"小红",变量hobby1的值为"学习",变量hobby的值为["学习"]。

function getUserInfo(uid) {

 	return {
 		status: true,
 		data: {
 			name: '小红'
 		},
		msg: '请求成功'
 	};
};

const { status, data, msg: message } = getUserInfo(123);

这段代码定义了一个名为getUserInfo的函数,该函数以一个参数uid作为输入,并返回一个包含status、data和msg等属性的对象。

在代码的最后,使用了ES6中的对象解构特性,将函数返回的对象中的属性值分别赋值给变量status、data和message。

具体来说,变量status的值等于对象属性status的值(即true),变量data的值等于对象属性data的值(即{name: '小红'}),变量message的值等于对象属性msg的值(即"请求成功")。

最终,通过解构赋值的方式,我们可以更方便地获取到函数返回的结果中的部分数据。

const str = 'I am the bone of my sword'; 
const [ a, b ,c, ...oth ] = str;

 const [ ...spStr1 ] = str;
 const spStr2 = str.split('');
 const spStr3 = [ ...str ];

 这段代码主要展示了如何对字符串进行解构和拆分操作。

首先,将字符串" I am the bone of my sword "赋值给变量str。然后,使用数组解构的方式,将字符串中的前三个字符依次赋值给变量a、b和c,剩余的字符则以数组形式赋值给变量oth。

接着,使用ES6中的扩展运算符(...)将字符串str转换为数组形式,即将其中每个字符分别作为数组的一个元素,保存在新数组spStr1中。此时,spStr1的值为["I", " ", "a", "m", " ", "t", "h", "e", " ", "b", "o", "n", "e", " ", "o", "f", " ", "m", "y", " ", "s", "w", "o", "r", "d"]。

接下来,使用字符串的split方法将字符串str按照空格字符分割为一个字符串数组,将该数组赋值给变量spStr2。此时,spStr2的值为["I", "am", "the", "bone", "of", "my", "sword"]。

最后,使用ES6中的扩展运算符,将变量str中的每个字符分别作为一个单独的元素保存在新数组spStr3中。跟spStr1的结果是一致的,值也是["I", " ", "a", "m", " ", "t", "h", "e", " ", "b", "o", "n", "e", " ", "o", "f", " ", "m", "y", " ", "s", "w", "o", "r", "d"]。

const { valueOf: vo } = 1;
const { toString: ts } = false;

这段代码使用了对象解构的方式,将数字1和布尔值false转化为对应的包装对象,然后将其属性分别解构赋值给变量vo和ts。

在第一个解构赋值语句中,由于数字1是一个原始值类型,JS会将其隐式地转化为Number对象,从而可以访问到Number对象原型上的valueOf方法,而对象解构则可以将该方法作为vo变量的值。

在第二个解构赋值语句中,boolean类型的false也会被隐式地转化为Boolean对象,从而可以访问到Boolean对象原型上的toString方法,该方法将被赋值给ts变量。

最终,vo变量的值为根据数字1创建的Number对象的valueOf方法,ts变量的值为根据布尔值false创建的Boolean对象的toString方法。

需要注意的是,由于本题中的解构赋值只是用来演示如何获取包装对象的原型方法。因此在实际开发中不建议使用解构赋值来获取原型方法,这样会使代码变得难以阅读和理解。

 function swap([x, y]) {
 	return [y, x];
 };

 let arr = [1, 2];
 arr = swap(arr);

这段代码定义了一个名为swap的函数,该函数接受一个数组作为参数,并返回该数组的第一个元素和第二个元素的值交换后的数组。

在主程序中,定义了一个名为arr的数组,并将值[1, 2]赋值给该数组。然后,调用swap函数并将arr作为参数传入。因为swap函数返回一个数组,所以可以将其直接赋值给arr。

但是这里需要注意的是,swap函数的参数x是一个普通变量,而y是一个引用变量。调用swap函数时传递的参数arr是一个引用(即数组在内存中的地址)。因此,在swap函数内部对y作值的修改实际上是在修改主程序中的arr数组。

最终,由于swap函数交换了arr数组中的元素顺序,因此arr的值被更新为[2, 1]。

function Computer({
	cpu,
	memory,
	software = ['ie6'],
	OS = 'windows 3.5'
}) {

	console.log(cpu);
	console.log(memory);
	console.log(software);
	console.log(OS);

};

new Computer({
	memory: '128G',
	cpu: '80286',
	OS: 'windows 10'
});

这段代码定义了一个构造函数Computer,该函数接受一个对象作为输入参数,对象包含cpu、memory、software和OS等属性。

在构造函数内部,使用ES6中的对象解构方式将参数对象中对应的属性值分别赋值给cpu、memory、software和OS这几个变量。

需要注意的是,对象解构中software的默认值为["ie6"],如果参数对象中未提供software属性,则会默认使用"ie6"作为其属性值。同时,OS的默认值为"windows 3.5",如果参数对象中未提供OS属性,则会默认使用"windows 3.5"作为其属性值。

在主程序中,使用new关键字创建了一个Computer对象,并将一个包含cpu、memory和OS等属性的对象作为参数传递给了该构造函数。

 <script>
    document.querySelector('button').addEventListener('click', function() {
      new $Msg({
        content: '真的要删除吗...',
        title: '确认删除',
        type: 'wrong',
        btnName: ['好的', '算了吧'],
        confirm: function(e) {
          console.log(this);
          console.log(e);
          new $Msg({
            content: '删除成功<span style="color: red">~</span>',
            type: 'success',
            footer: false,
            useHTML: true,
            header: false
          
          })
        },
        cancel: function(e) {
          document.querySelector('#t').innerHTML += '取消了,';
        }
      });
    });
  </script>

这段代码基于事件监听器开发了一个弹窗组件,当用户点击页面上的按钮时会触发事件处理函数。在事件处理函数中,以一个$Msg对象的形式创建了一个包含多个属性的弹窗,并设置了弹窗的标题、内容、类型、按钮名称、确认和取消回调函数等属性。

具体来说,当用户点击按钮时,代码会查找页面上该按钮对应的DOM元素,并调用addEventListener方法,监听click事件。在监听器函数中,通过new $Msg()的形式创建了一个$Msg对象,并将一个包含各种属性的配置对象作为参数传递给了该对象。

其中,$Msg对象是一个弹窗组件,它有多个配置项控制弹窗的外观和行为,这些配置项的含义如下:

- content:弹窗的内容。
- title:弹窗的标题。
- type:弹窗的类型,可以是success、info、warning或者error。
- btnName:自定义弹窗的按钮名称,包括确认和取消按钮。
- confirm:当用户点击确认按钮时的回调函数。
- cancel:当用户点击取消按钮时的回调函数。

在这段代码中,当用户点击确认按钮时,会打印出this和e的值,并且在控制台上输出一条成功消息。当用户点击取消按钮时,代码会修改页面上id为"t"的元素的innerHTML属性,添加一个取消的标记字符串。

整个代码的作用是在用户点击按钮时显示一个弹窗,提示用户是否确认删除。如果用户选择确认,则显示删除成功的消息;如果用户选择取消,则在页面上输出一个取消的标记

const xiaoming = {
 	name: 'xiaoming',
 	age: 14,
 	say1: function() {
 		console.log('我叫' + this.name.toUpperCase() + ', 我今年' + this.age + '岁!');
 	},
 	say2: function() {
 		console.log(`我叫${ `Mr.${ this.name.toUpperCase() }` }, 我今年${ this.age }岁!`);
 	}
 }

 xiaoming.say1();
 xiaoming.say2();

这段代码定义了一个名为"xiaoming"的对象,该对象具有以下属性:

- "name"表示名称,其值为"xiaoming"
- "age"表示年龄,其值为14
- "say1"是一个方法,它将输出"xiaoming"的大写名称和年龄
- "say2"也是一个方法,它将输出"Mr. xiaoming"和年龄

然后,通过调用xiaoming对象的两个方法say1()和say2()来运行这些方法。执行结果为:

我叫XIAOMING,我今年14岁!
我叫Mr. XIAOMING,我今年14岁!
 

const getImoocCourseList = function() {
	// ajax
	return {
		status: true,
		msg: '获取成功',
		data: [{
			id: 1,
			title: 'Vue 入门',
			date: 'xxxx-01-09'
		}, {
			id: 2,
			title: 'ES6 入门',
			date: 'xxxx-01-10'
		}, {
			id: 3,
			title: 'React入门',
			date: 'xxxx-01-11'
		}]
	}
};

const { data: listData, status, msg } = getImoocCourseList();

这段代码定义了一个函数getImoocCourseList(),它会执行一个Ajax请求,并返回一个包含status、msg和data属性的对象。其中,data属性是一个包含多个课程信息的数组,每个课程包含id、title和date属性。

然后,使用ES6中的解构赋值语法,将从getImoocCourseList()函数返回的对象解构为3个变量:listData、status和msg。这样,我们就可以通过listData变量来访问这些课程信息。

值得注意的是,在解构赋值中,我们将data属性直接赋值给了listData变量,这意味着我们可以更轻松地访问和操作课程信息,而无需使用冗长的dot notation。

if (status) {
    let arr = [];

    listData.forEach(function({ date, title }) {

        arr.push(
            `
				<li>
					<span>${ `课程名: ${ title }` }</span>
					<span>${ foo(date) }</span>
				</li>
			`
        );

    });

    let ul = document.createElement('ul');
    ul.innerHTML = arr.join('');

    document.body.appendChild(ul);

} else {
    alert(msg);
}

这段代码是一个条件判断,如果status为true,则会将listData数组中的每个课程信息提取出来,放入一个ul列表中,并将该ul元素添加到文档中。否则,将弹出一个警告框,显示msg中的信息。

具体地说,如果status为true,则会定义一个空数组arr,然后使用forEach()方法遍历listData数组中的每个元素,并通过模板字符串的方式将每个元素的date和title属性渲染到一个li元素中,最后将每个li元素都添加到arr数组中。然后,创建一个ul元素并使用innerHTML属性将arr数组的元素转换为HTML代码并插入到ul元素中。最后,将该ul元素添加到文档中。

<span>${ `课程名: ${ title }` }</span> 这段代码里的$的作用是什么

在这段代码中,$字符是一种模板字符串语法。模板字符串是一种新的字符串语法,它允许我们将表达式嵌入到字符串中。在表达式中,我们可以对变量进行运算、调用函数等操作,并将结果渲染到字符串中。

在此示例中,$字符的主要作用是将一个表达式嵌入到字符串中,表达式的结果将被渲染为字符串。具体来说,表达式`${ title }`表示将title变量的值嵌入到字符串中。

同时,$字符与大括号配合使用,可以方便地将表达式和其他文本结合起来。在这个例子中,我们使用`${ `课程名: ${ title }` }`将表达式`${ title }`嵌套在其他文本中,这使得我们可以将文本和表达式组合成一个字符串,最终的结果是渲染为`<span>课程名: xx</span>`的HTML代码,其中“xx”是title变量的值。

{
	let str = 'i';

	let str1 = str.padStart(5, 'mooc');
	console.log(str1);

	let str2 = str.padEnd(5, 'mooc');
	console.log(str2);
}

这段代码通过字符串的padStart()和padEnd()方法来实现对字符串的填充。

padStart()方法会在当前字符串的开始位置添加指定的字符串,直到字符串达到指定的长度。比如在代码中的"i"字符串前插入4个"mooc",使其总长度到达5。

padEnd()方法则是在字符串的结尾位置添加指定的字符串,直到字符串达到指定的长度。比如在代码中的"i"字符串后面插入4个"mooc",使其总长度到达5。

最终输出的结果为:
"mooci"
"imooc"

{
	   

	function repeat(str, num) {
		return new Array(num + 1).join(str);
	}
	console.log(repeat('s', 3));
}

这段代码定义了一个函数repeat,传入两个参数:字符串str和数字num。

在函数内部,先创建一个num+1长度的数组,然后调用数组的join方法,将数组拼接成一个字符串。

join方法的参数为str,这样数组中每个元素都会被字符串str连接起来,num+1的原因是为了保证最后字符串重复num次。

最终输出的结果就是字符串s重复3次,即"sss"。

数组的join方法是什么?为什么这段代码要num+1才能确保重复num次?console括号里面的3有什么作用?

数组的join方法是将数组中的所有元素转化为字符串并连接起来,连接符可以作为参数传入。如果不传入参数,则会默认使用 "," 作为连接符来连接数组元素。

这段代码要num+1才能确保重复num次的原因是,当构造一个长度为num的数组时,数组元素的下标从0到num-1,因此数组的长度只有num。但上述代码要求重复字符串num次,因此需要添加1,这样新构造的数组长度就为num+1,这样在执行join时保证了字符串被重复num次。

console括号里面的3是作为参数传递给函数repeat的,用来指定重复字符串的次数。在这里的作用是表示将字符s重复3遍的输出结果。

{
	const str = 'A promise is a promsie';

	console.log(str.startsWith('B'));
	console.log(str.startsWith('A pro'));

	console.log(str.endsWith('promsie'));
	console.log(str.endsWith('A'));
}

这段代码演示了字符串的startsWith()和endsWith()方法,用于检查字符串是否以指定的字符或字符串开始或结束。

startsWith()方法用来检查字符串是否以指定的字符或字符串开始,它接收一个参数,指定要检查的字符或字符串。如果字符串以该字符或字符串开始,则返回true,否则返回false。在这段代码中:

- str.startsWith('B')返回false,因为字符串str并不以字符'B'开始。
- str.startsWith('A pro')返回true,因为字符串str以字符串'A pro'开始。

endsWith()方法用来检查字符串是否以指定的字符或字符串结束,它接收一个参数,指定要检查的字符或字符串。如果字符串以该字符或字符串结束,则返回true,否则返回false。在这段代码中:

- str.endsWith('promsie')返回true,因为字符串str以字符串'promsie'结束。
- str.endsWith('A')返回false,因为字符串str不以字符'A'结束。

{
	const str = 'A promise is a promise';

	
	if (~str.indexOf('promise')) {
		console.log('存在1');
	}

	if (str.includes('a promise')) {
		console.log('存在2');
	}
}

这段代码演示了字符串的indexOf()和includes()方法,用于查找字符串中是否包含指定的字符或字符串,返回布尔值。

indexOf()方法接收一个参数,指定要查找的字符或字符串。如果找到该字符或字符串,返回该字符或字符串在原字符串中第一次出现的位置;未找到则返回-1。在这段代码中:

- 用 ~(按位取反)运算符对str.indexOf('promise')结果取反,结果为false,表示字符串中不包含'promise'。
- ~str.indexOf()在JS中用来快速判断某字符/子串是否存在,因为如果子串不存在,返回的是-1,而按位反码后都会转化为 true。

includes()方法也接收一个参数,指定要查找的字符或字符串。如果找到该字符或字符串,返回true,否则返回false。在这段代码中:

- str.includes('a promise')返回true,因为字符串str包含子字符串'a promise'。

综上所述,代码中的if语句通过indexOf()和includes()方法来检查字符串中是否包含指定字符或字符串,当检查结果为true时,在控制台输出相应的信息。

 如果没有按位取反符号 ~的结果会有什么差别?

如果没有使用按位取反符号 ~,那么代码在判断字符串'str'是否包含子串'promise'时,只会返回一个数值,而不是布尔值。

具体来说,'~str.indexOf('promise')'语句会返回一个数值,如果找到'promise'子串,则返回一个非-1的数字,并且这个数字按位取反后返回false,否则如果未找到'promise'子串,则返回-1,按位取反后返回true。而如果没有使用 ~ 符号,则返回的是数字,位运算符只能对数字进行按位取反,无法直接作用于字符串,因此无法直接获得字符串是否包含指定子串的结果,需要通过数字转换为布尔值来表示是否找到子串的结果。

 for (var i = 0, len = str.length; i < len; i ++) {
 	console.log(str[i]);
 	console.log(str.charAt(i));
 }

这段代码通过循环遍历字符串中的每个字符,输出字符的值以及通过charAt()方法得到的字符值。

循环遍历的方式是通过for循环,循环变量i从0开始逐步增加,直到字符串的长度len(因为字符串下标是从0开始的),逐个输出字符串中的字符。

在循环体内,通过数组下标方式输出字符的值,即使用str[i]实现。同时,通过JavaScript String对象的charAt()方法获得整个字符串的每一个字符,实现方式是使用str.charAt(i)。

var oStr = Array.prototype.slice.call(str);
var oStr = str.split('');
 const oStr = [...str];
 const [...oStr] = str;

 oStr.forEach(function(word) {
 	console.log(word);
 });

 console.log(oStr);

这段代码通过不同的方式将字符串转化为字符数组,并遍历输出每个字符。

首先,通过Array.prototype.slice.call()方法可以将字符串str转换为字符数组oStr。这种方式通过Array原型链上的slice方法,创建一个新的包含所有字符的数组。

其次,可以使用split()方法将字符串str分割成由单个字符组成的数组,得到字符数组oStr。在这里,分隔符是空字符串,即用空字符将字符串分割成单个字符。这种方式比较简单,但效率略低。

接着,使用ES6的展开运算符(...),也可以很方便地将字符串str转变为字符数组oStr。在这个方式中,注意展开运算符要放在一个外层数组内,用于将输入的字符串转化为单个字符组成的数组。

最后,通过forEach()方法对oStr字符数组进行遍历,逐个输出每个字符。

最终,通过console.log(oStr)输出整个字符数组oStr。

const map = {A: '100', B: '99', C: '98', D: '97', E: '96', F: '95', G: '94', H: '93', I: '92', J: '91', K: '90', L: '89', M: '88', N: '87', O: '86', P: '85', Q: '84', R: '83', S: '82', T: '81', U: '80', V: '79',W: '78',X: '77',Y: '76', Z: '75'};
const words = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

oStr.forEach(function(word, index) {
	if (words.includes(word)) oStr[index] = map[word];
});

console.log(oStr.join(''));

这段代码将字符数组oStr中的每个元素与大写字母表字符串words进行比较,查找当前字符是否是大写字母。如果是大写字母,则根据映射表map中的键值将该字符的值替换。最后将所有替换后的字符连接起来,输出结果。

具体来说,代码中首先调用数组oStr的forEach方法,开始遍历字符数组。在forEach的回调函数中,对于数组中的每个元素,判断其是否为大写字母,如果是,则根据其在映射表map对象中对应的键名,将其在数组中对应的值替换成map对象中的键值。

最后,调用数组oStr的join('')方法将修改后的字符数组变成字符串,并且把字符以空字符串为分隔符连接成一个完整的字符串,将结果输出到控制台。

使用for of遍历字符串(最简短,可读性最高)

let newStr = '';
for (let word of str) {
	if (words.includes(word)) newStr += map[word];
}
console.log(newStr)

具体实现方式是:声明一个空字符串newStr,通过for...of循环遍历字符串str中的每个字符,判断当前字符是否是大写字母,如果是,则从映射表map对象中获取该字符相应的得分,并将其加到空字符串newStr中。最终,将newStr字符串输出到控制台,即输出转换后的结果。

与之前的代码相比,这段代码在遍历字符串时使用了for...of循环,这是ES6新特性之一,该语句可以用来遍历字符串、数组等可迭代对象。同时,也可以使用模板字符串实现字符串拼接,这样代码可读性更高。

2-9

编程练习:

在Java中,可以使用两种方法将一个数组的内容复制到另一个数组:(将a复制到B上)

 System.arraycopy(a, 0, b, 0, a.length);

在这个示例中,`arraycopy()`方法将`a`数组的数据复制到`b`数组,开始复制位置为`a`数组的起始位置(0),目标位置为`b`数组的起始位置(0),复制的长度为`a`数组的长度(`a.length`)。

int[] help = nums.clone()

这段代码是在Java语言中声明一个整型数组help,并将另一个整型数组nums的副本赋值给help数组。

具体来说, nums.clone() 的作用是创建一个原数组 nums 的副本,其长度和内容都与原数组相同,然后将这个副本作为一个新数组返回。

因此,上述代码相当于将 nums 数组中的所有元素复制到 help 数组中,从而得到具有相同长度和内容的另一个整型数组。

需要注意的是,使用clone()方法生成数组副本时,副本和原数组是独立的,对其中一个进行修改不会影响另一个。

给你一个整数数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序。

你可以假设所有输入数组都可以得到满足题目要求的结果。

class Solution {
  public void wiggleSort(int[] nums) {
        int[] help = nums.clone(); //不能写成int[] help = nums,排序后两个数组都改变
        Arrays.sort(help);
        int N = nums.length;
        //比如123456
        for (int i = 1; i < nums.length; i += 2) {
            nums[i] = help[--N]; //遍历完成后 x 6 x 5 x 4 
        }
        for (int i = 0; i < nums.length; i += 2) {
            nums[i] = help[--N]; //便利完成后 3 6 2 5 1 4
        }
    }
}

java里将一个数组所有元素变成0的代码:

Arrays.fill(arr,0);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值