现有有一个大于等于 2 的正整数 a ,现在我们需要判断这个数字是不是质数。质数是只有 1 和它自己两个因数的数。对于所有的大于 2 的数,我们需要枚举那些大于 2 小于等于根号 a 的所有数字,一一确定它们是不是 a 的因数,如果都找不到那么它肯定是质数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
let a = 114514; // 很明显这是个合数 let isPrime = false; // 一个 boolen ,记录是否为质数
if (a === 2) { isPrime = true; } else { isPrime = true; // 先暂时赋值,如果后面没被覆盖肯定是质数 for (let i = 2; i <= Math.sqrt(a); i++) { if (a % i === 0) { isPrime = false; } } }
if (isPrime) { console.log("是质数。"); } else { console.log("不是质数。"); }
看起来很合理,但是如果有三个数,分别是 a, b, c。或者有三十个数,你是不是要把上面那个 if else 和循环都复制一下?这么做的话太麻烦了。所以我们有更好的方法:函数 (function) 。这就是上面写成函数的例子:
functiontest(x) { console.log("In function test, x = " + x); x = 3; console.log("After you changed, x = " + x); }
let a = 1; console.log("Before called the function, a = " + a); test(a); console.log("After called the function, a = " + a);
输出:
1 2 3 4
Before called the function, a = 1 In function test, x = 1 After you changed, x = 3 After called the function, a = 1
是不是非常清楚,函数 test 改了一个寂寞,最后 a 的值还是没变,其实函数的参数传递,就类似对每个参数进行了一次赋值,函数里面的变量和外面的不是同一个变量。类似的,如果传入的是数组和对象,情况就不太一样了:
1 2 3 4 5 6 7 8 9 10
functiontest(x) { console.log("In function test, x = " + x.join(',')); x[0] = 3; console.log("After you changed, x = " + x.join(',')); }
let a = [1, 3, 5]; console.log("Before called the function, a = " + a.join(',')); test(a); console.log("After called the function, a = " + a.join(','));
输出:
1 2 3 4
Before called the function, a = 1,3,5 In function test, x = 1,3,5 After you changed, x = 3,3,5 After called the function, a = 3,3,5
定义域
函数里面的定义的值不会占用掉外面的名称,更不会占用掉其他函数里面定义的变量名。比如说这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
let x = "x global";
functiontest1() { let x = "x in test1()"; console.log(x); }
functiontest2() { let x = "x in test2()"; console.log(x); }
test1(); test2(); console.log(x);
输出:
1 2 3
x in test1() x in test2() x global
函数和对象
我们之前谈过了对象,现在是进一步扩充它的时候了。
函数作为值
函数可以被作为一个值赋值给一个变量:
1 2 3 4 5
functionadd(a, b) { return a + b; } let myadd = add; let x = myadd(1, 3);
<!DOCTYPE html> <htmllang="en"> <head> <metacharset="UTF-8"> <title>JS Example</title> </head> <body> <!-- 内部 JS --> <script> console.log("Hello, I am a JS CODE!"); console.log("Hello, I am the second line!"); </script>
<p>Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts. Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean.</p>
您可以更改此默认显示行为。例如,<li> 元素默认为display:block,这意味着在我们的英文文档中,列表项显示为一个在另一个之下。如果我们将显示值更改为inline,它们现在将显示在彼此旁边,就像单词在句子中所做的那样。事实上,您可以更改任何元素的display值,这意味着您可以根据它们的语义选择 html 元素,而不必关心它们的外观。他们的样子是你可以改变的。
让我们来看一个例子。首先,创建 HTML 表单的一些简单标记。每个输入元素都有一个标签,我们还在一个段落中包含了一个标题。为了进行布局,每个标签/输入对都封装在 <div> 中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<form> <p>First of all, tell us your name and age.</p> <div> <labelfor="fname">First name:</label> <inputtype="text"id="fname"> </div> <div> <labelfor="lname">Last name:</label> <inputtype="text"id="lname"> </div> <div> <labelfor="age">Age:</label> <inputtype="text"id="age"> </div> </form>
粘性定位(Sticky positioning)是一种新的定位方式,它会让元素先保持和 position: static 一样的定位,当它的相对视口位置(offset from the viewport)达到某一个预设值时,他就会像 position: fixed一样定位。
如果看不明白,就了解下我们下面的例子吧。
简单定位示例
我们将展示一些示例代码来熟悉这些布局技术. 这些示例代码都作用在下面这一个相同的HTML上:
1 2 3 4
<h1>Positioning</h1> <p>I am a basic block level element.</p> <pclass="positioned">I am a basic block level element.</p> <p>I am a basic block level element.</p>